Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Manajemen akun pengguna, peran, izin, otentikasi PHP dan MySQL -- Bagian 5

Ini adalah bagian 5 dari seri tentang cara membuat sistem pengelolaan akun pengguna di PHP. Anda dapat menemukan bagian lainnya di sini:bagian1, bagian2, bagian 3 dan bagian 4.

Kami selesai mengelola akun pengguna administratif di bagian terakhir serta peran. Di bagian ini, kita akan melalui pembuatan izin dan penetapan dan pembatalan penetapan izin untuk peran pengguna.

Menetapkan izin ke peran

Seperti yang saya katakan di bagian pertama seri ini, peran terkait dengan izin dalam hubungan Banyak-Ke-Banyak. Sebuah peran dapat memiliki banyak izin dan izin dapat dimiliki oleh banyak peran.

Kami telah membuat tabel peran. Sekarang kita akan membuat tabel izin untuk menyimpan izin dan tabel ketiga bernama permission_role untuk menyimpan informasi tentang hubungan antara peran dan tabel izin.

Buat dua tabel untuk memiliki properti berikut:

tabel izin:

CREATE TABLE `permissions` (
 `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 `name` varchar(255) NOT NULL UNIQUE KEY,
 `description` text NOT NULL
)

tabel permission_role:

CREATE TABLE `permission_role` (
 `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
 `role_id` int(11) NOT NULL,
 `permission_id` int(11) NOT NULL,
 KEY `role_id` (`role_id`),
 KEY `permission_id` (`permission_id`),
 CONSTRAINT `permission_role_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `permission_role_ibfk_2` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`)
)

Pada tabel permission_role, role_id mereferensikan id peran pada tabel peran, sedangkan permission_id mereferensikan kolom id izin pada tabel izin. Untuk menetapkan izin ke suatu peran, kami melakukannya dengan hanya memasukkan catatan dari izin_id itu terhadap peran_id pada tabel izin_peran dan hubungan dibuat. Ini berarti jika kita ingin membatalkan penetapan izin itu dari peran itu, kita cukup menghapus catatan role_id itu terhadap izin_id itu di tabel permission_role ini.

Dua baris terakhir dari kueri SQL di atas adalah batasan yang memastikan bahwa ketika peran atau izin tertentu dihapus, semua entri dalam tabel permission_role yang memiliki id izin atau id peran tersebut juga akan dihapus secara otomatis oleh database. Kami melakukan ini karena kami tidak ingin tabel permission_role menyimpan informasi hubungan tentang peran atau izin yang tidak ada lagi.

Anda juga dapat mengatur batasan ini secara manual menggunakan PHPMyAdmin:Anda dapat melakukannya di antarmuka hanya dengan memilih tabel permission_role dan membuka tampilan Relasional> tab Struktur dan hanya mengisi nilainya. Jika Anda masih tidak dapat melakukannya, tinggalkan komentar di bawah dan saya akan mencoba membantu Anda.

Sekarang hubungan diatur.

Mari buat halaman untuk menetapkan izin ke peran. Pada halaman roleList.php kami, kami mencantumkan berbagai peran dengan tombol 'izin' di samping masing-masing. Mengklik tautan ini akan membawa kita ke halaman bernama assignPermissions.php. Mari kita buat file itu sekarang di dalam folder admin/roles.

assignPermissions.php:

<?php include('../../config.php') ?>
<?php include(ROOT_PATH . '/admin/roles/roleLogic.php') ?>
<?php
  $permissions = getAllPermissions();
  if (isset($_GET['assign_permissions'])) {
    $role_id = $_GET['assign_permissions']; // The ID of the role whose permissions we are changing
    $role_permissions = getRoleAllPermissions($role_id); // Getting all permissions belonging to role

    // array of permissions id belonging to the role
    $r_permissions_id = array_column($role_permissions, "id");
  }
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Admin Area - Assign permissions </title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custome styles -->
  <link rel="stylesheet" href="../../static/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>
  <div class="col-md-4 col-md-offset-4">
    <a href="roleList.php" class="btn btn-success">
      <span class="glyphicon glyphicon-chevron-left"></span>
      Roles
    </a>
    <hr>
    <h1 class="text-center">Assign permissions</h1>
    <br />
    <?php if (count($permissions) > 0): ?>
    <form action="assignPermissions.php" method="post">
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>N</th>
            <th>Role name</th>
            <th class="text-center">Status</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach ($permissions as $key => $value): ?>
            <tr class="text-center">
              <td><?php echo $key + 1; ?></td>
              <td><?php echo $value['name']; ?></td>
              <td>
                  <input type="hidden" name="role_id" value="<?php echo $role_id; ?>">
                  <!-- if current permission id is inside role's ids, then check it as already belonging to role -->
                  <?php if (in_array($value['id'], $r_permissions_id)): ?>
                    <input type="checkbox" name="permission[]" value="<?php echo $value['id'] ?>" checked>
                  <?php else: ?>
                    <input type="checkbox" name="permission[]" value="<?php echo $value['id'] ?>" >
                  <?php endif; ?>
              </td>
            </tr>
          <?php endforeach; ?>
          <tr>
            <td colspan="3">
              <button type="submit" name="save_permissions" class="btn btn-block btn-success">Save permissions</button>
            </td>
          </tr>
        </tbody>
      </table>
    </form>
    <?php else: ?>
      <h2 class="text-center">No permissions in database</h2>
    <?php endif; ?>
  </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
</body>
</html>

Mengklik tombol 'izin' dari sebuah peran akan mengarahkan Anda ke halaman ini. Tapi sekarang jika Anda mengkliknya dan datang ke halaman assignPermissions.php ini, ada pesan kesalahan yang mengatakan fungsi getAllPermissions() tidak terdefinisi. Sebelum kita menambahkan metode ini, mari kita bahas bagaimana sebenarnya kita mengimplementasikan penetapan dan penghapusan izin ini dalam kode PHP kita.

Ketika Anda mengklik tombol 'izin' dari sebuah peran, Anda akan dibawa ke halaman assignPermissions.php dengan id peran itu. Namun sebelum menampilkan halaman tetapkan izin, kami menggunakan id peran untuk mengambil semua izin yang telah ditetapkan ke peran tersebut dari database. Dan kemudian kami juga mengeluarkan semua izin yang tersedia di tabel izin. Sekarang kami memiliki dua larik izin:yang telah ditetapkan ke peran dan semua izin yang tersedia di database kami. Satu yang pertama adalah bagian dari yang terakhir.

Menetapkan izin ke peran berarti menambahkan izin itu dari keseluruhan daftar izin ke larik izin milik peran itu dan menyimpan seluruh info ini di tabel permission_role. Membatalkan penetapan izin dari peran berarti menghapus izin tertentu dari daftar izin yang dimiliki peran tersebut.

Logika kami adalah untuk mengulang array semua izin yang tersedia dari database, kemudian untuk masing-masing id mereka, kami menentukan apakah id itu sudah ada dalam larik id untuk izin peran. jika ada, itu berarti peran tersebut sudah memiliki izin itu sehingga kami menampilkannya di samping kotak centang yang dicentang. Jika tidak ada, kami menampilkannya di samping kotak centang yang tidak dicentang.

Setelah semuanya ditampilkan, mengklik kotak centang yang dicentang berarti membatalkan penetapan izin sementara mengklik kotak centang yang tidak dicentang berarti menetapkan izin ke peran. Setelah semua centang dan hapus centang selesai, pengguna kemudian mengklik tombol 'Simpan Izin' di bawah tabel untuk menyimpan semua izin yang telah diperiksa untuk peran itu.

Mari tambahkan semua fungsi ini ke file roleLogic.php. Mereka adalah:

roleLogic.php:

// ... other functions up here ...
  function getAllPermissions(){
    global $conn;
    $sql = "SELECT * FROM permissions";
    $permissions = getMultipleRecords($sql);
    return $permissions;
  }

  function getRoleAllPermissions($role_id){
    global $conn;
    $sql = "SELECT permissions.* FROM permissions
            JOIN permission_role
              ON permissions.id = permission_role.permission_id
            WHERE permission_role.role_id=?";
    $permissions = getMultipleRecords($sql, 'i', [$role_id]);
    return $permissions;
  }

  function saveRolePermissions($permission_ids, $role_id) {
    global $conn;
    $sql = "DELETE FROM permission_role WHERE role_id=?";
    $result = modifyRecord($sql, 'i', [$role_id]);

    if ($result) {
      foreach ($permission_ids as $id) {
        $sql_2 = "INSERT INTO permission_role SET role_id=?, permission_id=?";
        modifyRecord($sql_2, 'ii', [$role_id, $id]);
      }
    }

    $_SESSION['success_msg'] = "Permissions saved";
    header("location: roleList.php");
    exit(0);
  }

Menempatkan izin untuk bekerja

Pada titik ini, kami dapat menentukan apa peran pengguna dan karena peran tersebut terkait dengan izin, oleh karena itu kami juga dapat mengetahui izin mereka.

Sekarang kami ingin menerapkan izin ini: yaitu, untuk memastikan bahwa pengguna admin hanya diizinkan untuk melakukan tindakan yang izinnya ia miliki. Kami akan mencapai ini menggunakan fungsi middleware. Middleware pada dasarnya adalah sepotong kode atau fungsi yang dieksekusi sebelum suatu tindakan dilakukan. Biasanya, fungsi middleware ini dapat mengubah perilaku tindakan atau melakukan beberapa pemeriksaan yang mungkin berakhir menghentikan tindakan sama sekali tergantung pada hasil pemeriksaan.

Misalnya, pengguna mungkin memiliki izin buat-posting, update-posting, dan hapus-posting. Jika mereka masuk dan mencoba memublikasikan postingan, fungsi middleware kami akan memeriksa terlebih dahulu untuk melihat apakah pengguna ini memiliki izin publikasikan-posting. Jika mereka memiliki izin ini, fungsi middleware kami akan kembali benar dan pos akan dipublikasikan. Jika mereka tidak memiliki izin publish-post, fungsi middleware kami akan mengarahkan mereka kembali dengan pesan yang mengatakan bahwa mereka tidak memiliki izin untuk mempublikasikan posting.

Kami akan menempatkan semua fungsi middleware kami di dalam satu file bernama middleware.php. Buat sekarang di folder admin dan tempel kode ini ke dalamnya:

middleware.php:

<?php

  // if user is NOT logged in, redirect them to login page
  if (!isset($_SESSION['user'])) {
    header("location: " . BASE_URL . "login.php");
  }
  // if user is logged in and this user is NOT an admin user, redirect them to landing page
  if (isset($_SESSION['user']) && is_null($_SESSION['user']['role'])) {
    header("location: " . BASE_URL);
  }
  // checks if logged in admin user can update post
  function canUpdatePost($post_id = null){
    global $conn;

    if(in_array('update-post', $_SESSION['userPermissions'])){
      if ($_SESSION['user']['role'] === "Author") { // author can update only posts that they themselves created
          $sql = "SELECT user_id FROM posts WHERE id=?";
          $post_result = getSingleRecord($sql, 'i', [$post_id]);
          $post_user_id = $post_result['user_id'];

          // if current user is the author of the post, then they can update the post
          if ($post_user_id === $user_id) {
            return true;
          } else { // if post is not created by this author
            return false;
          }
      } else { // if user is not author
        return true;
      }
    } else {
      return false;
    }
  }

  // accepts user id and post id and checks if user can publis/unpublish a post
  function canPublishPost() {
    if(in_array(['permission_name' => 'publish-post'], $_SESSION['userPermissions'])){
      // echo "<pre>"; print_r($_SESSION['userPermissions']); echo "</pre>"; die();
      return true;
    } else {
      return false;
    }
  }

  function canDeletePost() {
    if(in_array('delete-post', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canCreateUser() {
    if(in_array('create-user', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canUpdateUser() {
    if(in_array('update-user', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canDeleteUser() {
    if(in_array('delete-user', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canCreateRole($role_id) {
    if(in_array('create-role', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canUpdateRole($role_id) {
    if(in_array('update-role', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
  function canDeleteRole($user_id, $post_id) {
    if(in_array('delete-role', $_SESSION['userPermissions'])){
      return true;
    } else {
      return false;
    }
  }
?>
"; mati(); kembali benar; } else { kembali salah; } } function canDeletePost() { if(in_array('delete-post', $_SESSION['userPermissions'])){ mengembalikan true; } else { kembali salah; } } function canCreateUser() { if(in_array('create-user', $_SESSION['userPermissions'])){ mengembalikan true; } else { kembali salah; } } function canUpdateUser() { if(in_array('update-user', $_SESSION['userPermissions'])){ mengembalikan true; } else { kembali salah; } } function canDeleteUser() { if(in_array('delete-user', $_SESSION['userPermissions'])){ mengembalikan true; } else { kembali salah; } } function canCreateRole($role_id) { if(in_array('create-role', $_SESSION['userPermissions'])){ mengembalikan true; } else { kembali salah; } } function canUpdateRole($role_id) { if(in_array('update-role', $_SESSION['userPermissions'])){ mengembalikan true; } lain { kembali salah; } } function canDeleteRole($user_id, $post_id) { if(in_array('delete-role', $_SESSION['userPermissions'])){ return true; } else { kembali salah; } }?>

Pernyataan if pertama memeriksa apakah pengguna telah masuk. Jika pengguna tidak masuk, mereka akan diarahkan ke beranda. Pernyataan if kedua memeriksa apakah pengguna masuk dan apakah dia memiliki peran (adalah admin). Jika pengguna ditemukan masuk dan memiliki peran, mereka akan mengakses halaman, jika tidak, akan diarahkan kembali ke beranda.

Di setiap file di mana Anda ingin membatasi akses pengguna non-admin, Anda harus memasukkan file middleware.php ini ke dalam file itu. Jadi semua file admin kami yang tidak ingin diakses oleh pengguna biasa, kami akan menyertakan file ini di dalamnya. Jadi buka semua file di dua folder di dalam folder admin yaitu:pengguna, peran. Di setiap file, tambahkan baris berikut tepat di bawah sertakan untuk config.php.

Seperti ini:

<?php include('../../config.php'); ?>
<?php require_once '../middleware.php'; ?>

Dan itu akan mengarahkan pengguna non-admin yang mencoba mengunjungi halaman tersebut.

Juga dalam file middleware.php ini, kami menggunakan in_array() PHP untuk memeriksa apakah izin yang kami uji ada dalam larik izin pengguna tersebut. (Saat pengguna admin masuk, kami menempatkan semua izin mereka dalam larik variabel sesi yang disebut $_SESSION['userPermissions'].) Jika izin saat ini ada dalam larik izin pengguna, itu berarti bahwa pengguna memiliki izin itu dan oleh karena itu fungsi mengembalikan true, jika tidak mengembalikan false.

Sekarang jika Anda ingin memeriksa apakah pengguna memiliki izin, katakan izin publish-post yang harus Anda lakukan adalah memanggil metode canPublishPost() seperti ini:

<?php if (canPublishPost()): ?>
	<!-- User can publish post. Display publish post button -->
<?php else: ?>
	<!-- User cannot publish post. Do not display publish post button -->
<?php endif ?>

Juga sebagai middleware, sebelum kita mengupdate sebuah postingan, kita akan memanggil fungsi middleware canUpdatePost() terlebih dahulu. Jika fungsi memeriksa dan melihat bahwa pengguna tidak memiliki izin posting-perbarui, itu akan mengembalikan false dan kami kemudian dapat mengarahkan mereka ke beranda dengan pesan yang mengatakan bahwa dia tidak diizinkan untuk memperbarui posting. Seperti ini:

// checks if logged in admin user can update post
function updatePost($post_values){
  global $conn;

  if(canUpdatePost($post_values['id']){
     // proceed to update post
  
  } else {
    // redirect back to homepage with message that says user is not permitted to update post
  }
}

Hal yang sama untuk memublikasikan/membatalkan publikasi postingan:

function togglePublishPost($post_id)
{
	if (!canPublishPost($_SESSION['user']['id'])) {
		// redirect them back to dashboard with the message that they don't have the permission to publish post
	} 
    
    // proceed to publish post

}

Sekarang kita tinggal di bagian terakhir dari tutorial ini yang memperbarui profil pengguna dan juga memberi pengguna yang terdaftar kemampuan untuk menghapus akun mereka sendiri.

Terima kasih telah mengikuti. Jika Anda memiliki sesuatu untuk dikatakan, silakan tulis di komentar.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mengimpor dan mengekspor database MySQL

  2. Migrasi dari MySQL ke PostgreSQL - Yang Harus Anda Ketahui

  3. MySQL DROP COLUMN

  4. Kesalahan 1022 - Tidak dapat menulis; duplikat kunci dalam tabel

  5. Cara Mendapatkan Tanggal dan Waktu Saat Ini di MySQL