Advertisement
  1. Code
  2. PHP

Bagaimana menggunakan CakePHP Access Control List

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Dika Budiaji (you can also view the original English article)

Jika Anda sedang membuat sebuah CMS, Anda mungkin perlu user role yang berbeda-superusers, admin, user — dengan permission level yang berbeda. code yang terlalu rumit? Masukkan CakePHP ACL (Access Control List). Dengan setup yang benar, Anda akan memeriksa user permission dengan hanya satu baris.

Pendahuluan: Apakah itu Access Control List?

ACL memungkinkan Anda membuat hierarki user dengan role mereka masing-masing. Berikut adalah sebuah contoh cepat.

  • Super User
    • User #1
  • Admin
    • User #2
    • User #3
  • Users
    • User #4
    • User #5
    • User #6
    • ....

Dalam tutorial ini, kita akan menyiapkan ACL untuk blog sederhana. Jika Anda belum belum memeriksa Memulati dengan CakePHP (dan bagian 2) di sini di Nettuts +, silahkan melakukannya dan kemudian kembali, seperti yang kita akan mengambil untuk diberikan dasar-dasar framework.

Dengan hirarki ini, kami dapat memberikan beberapa permission untuk setiap role:

  • Super User memungkinkan po untuk create, read, update dan delete Post dan User.
  • Admin dapat create, read, update dan menghapus Post.
  • User bisa create dan read post.
  • Lainnya hanya bisa read post.

Setiap permission akan diberikan kepada grup, bukan untuk user; sehingga jika user #6 dipromosikan ke Admin, ia akan diperiksa terhadap grup permission--tidak nya. Role dan child node (user) ini disebut Access Request Objects, atau AROs.

Sekarang, di sisi lain, kita memiliki  Access Control Objects, atau ACO. Ini adalah objek untuk dikendalikan. Di atas saya sebutkan Post dan User. Biasanya, objek-objek ini secara langsung terkait dengan model, sehingga jika kita memiliki Post model, kita akan membutuhkan ACO untuk model ini.

ACO masing-masing memiliki empat dasar permission: create, read, update dan delete. Anda bisa mengingat mereka dengan kata kunci CRUD. Ada izin kelima, asterisk, itulah cara pintas untuk akses penuh.

Kami akan menggunakan hanya dua ACO untuk tutorial ini: Post dan User, tetapi Anda dapat membuat sebanyak yang Anda butuhkan.

Tabel ACL

Mari kita lanjutkan untuk membuat tabel database. Anda dapat menemukan kode ini di db_acl.sql di dalam app's config/sql direktori.

Kita dapat mulai sekarang menciptakan node ARO dan ACO, tapi hei, kita tidak punya user! Kita akan membuat sistem otentikasi dasar.


Langkah 1: Sistem otentikasi dasar

Seperti tutorial ini ditujukan untuk pengembang CakePHP dengan dasar pengenalan moderat framework, aku akan memasok kode dan penjelasan singkat. Namun, sistem otentikasi bukanlah tujuan dari tutorial ini.

Tabel MySQL:

Model User (models/user.php)

Users controller (controllers/users_controller.php)

Karena kita memiliki unsur-unsur baru, mari kita tinjau mereka. Pertama, kita menetapkan variabel $components. Variabel ini mencakup semua komponen dalam array. Kita akan membutuhkan Auth komponen, yang merupakan komponen inti, seperti HTML dan Form helper, tetapi sejak itu tidak disertakan secara default dengan Cake, kita akan memasukkan secara manual.

Komponen Auth menangani beberapa mekanisme otentikasi dasar: ini membantu kita untuk login user, menangani user yang dikonfirmasi sesi untuk kita, serta penanganan log keluar dan otorisasi dasar untuk tamu. Juga, itu hash password secara otomatis. Saya akan menjelaskan bagaimana memanggil fungsi masing-masing dalam paragraf berikut.

Selanjutnya, kami membuat sebuah fungsi yang disebut beforeFilter. Ini merupakan fungsi callback dan itu mari kita mengatur beberapa tindakan sebelum semua controller logika diproses. Auth komponen memerlukan kita untuk menentukan sebuah model untuk digunakan, dalam hal ini User. Kemudian, secara default, itu akan menolak semua akses ke user yang belum masuk. Kita akan memiliki untuk menimpa perilaku ini dengan allow() yang memerlukan satu parameter. Parameter dapat asterisk, menetapkan bahwa semua metode dalam berkata controller dapat diakses oleh user tidak terauthentikasi. Atau, dapat di pass sebuah array dengan fungsi-fungsi yang dapat diakses oleh user tidak terauthentikasi. Dalam hal ini, karena kita memiliki hanya tiga fungsi, baris berikut adalah hal yang sama.

Untuk fungsi login(), komponen Auth akan menangani semua mekanisme login untuk kita. Kita hanya perlu menyediakan fungsi dengan array dengan dua kunci: username dan password. Kunci ini dapat diubah, tetapi secara default, bidang username dan password akan dicocokkan database dan akan mengembalikan true jika user telah dikonfirmasi.

Akhirnya, fungsi login controller akan mencoba untuk mencocokkan kombinasi nama username/password terhadap database.

Harap dicatat bahwa kode ini sangat dasar. Anda akan perlu untuk memvalidasi karakter username, jika ada username, panjang minimum untuk password, dan sebagainya.

Register view (views/users/register.ctp)

Login view (views/users/login.ctp)

Buka /users/register di peramban web dan daftar akun baru. Saya sarankan admin sebagai username dan 123 seperti password dan jika sesi berakhir hanya pergi ke /users/login dan memasukkan kombinasi nama username/password benar yang baru Anda buat.


Langkah 2: Menolak akses pengguna tidak terauthentikasi

Kami bahkan tidak bekerja dengan ACL, tapi kita sudah dapat menyangkal post, editing dan deleting post. Buka Post controller Anda dan menambahkan komponen Auth.

Sekarang buka /posts di peramban web Anda. Jika Anda login, Anda akan melihat post, tetapi jika Anda tidak, Anda akan diarahkan ke /users/login. Dengan hanya memasukan komponen Auth, semua tindakan yang secara default, menolak untuk guest. Kita perlu menolak tiga aksi untuk user yang tidak sah: create, edit dan delete. Kata lain, kita akan memiliki untuk memungkinkan index dan view.

Pergi untuk mengedit atau membuat suatu post; Jika Anda sedang tidak login, Anda harus diarahkan ke /users/login. Segala sesuatu tampaknya bekerja cukup baik, bagaimana tentang view? edit dan delete link sedang ditampilkan kepada semua orang. Kita harus membuat conditional.

Tapi sebelum pergi ke itu, mari kita lihat bagaimana fungsi Auth's user() bekerja. Salin dan sisipkan baris-baris berikut ke fungsi indeks.

Membuka /posts Anda di browser Anda dan, jika log in, pr() akan melemparkan sesuatu seperti ini.

Fungsi user() mengembalikan array seperti model akan lakukan. Jika kita memiliki lebih dari tiga bidang (password ini tidak termasuk), mereka akan ditampilkan dalam array. Jika Anda tidak login, array akan kosong, sehingga Anda dapat mengetahui user masuk jika Auth's user() array tidak kosong.

Sekarang, Auth adalah komponen, dimaksudkan untuk digunakan dalam controller. Kita perlu tahu dari view jika pengguna log in, sebaiknya melalui helper. Bagaimana kita bisa menggunakan komponen dalam helper? CakePHP sangat mengagumkan dan fleksibel bahwa mungkin.

Menyimpan snippet ini di views/helpers sebagai access.php. Sekarang mari kita lihat kode, baris demi baris. Pertama, kami sedang mengatur $helpers var. Helper dapat di include di pembantu lain, seperti $components. Komponen Session yang diperlukan untuk komponen Auth, tetapi kita tidak memiliki akses ke komponen ini dalam helper. Untungnya kami memiliki Session helper, yang akan membantu kita.

Selanjutnya, kami membuat fungsi dan menggunakan App::import yang akan Mari kita mengimpor elemen yang biasanya kita tidak memiliki akses ke. Baris berikutnya membuat Auth komponen dalam variabel $auth, dan sekarang sedikit kotor hack; karena komponen Auth membaca sesi untuk mengetahui apakah kita login atau tidak, itu memerlukan komponen Session, tetapi seperti yang kita mengimpor itu dari tempat itu tidak boleh milik, kita harus memberikan objek Session baru. Akhirnya, kita menggunakan user() dan pengaturan untuk $user dan mengembalikan nilai true jika variabel tidak kosong, jika tidak mengembalikan nilai false.

Mari kita kembali ke controller post dan lanjutkan untuk menambahkan helper.

access helper ini sekarang dapat diakses dari view. Buka index.ctp di views/posts dan ganti baris ini.

Dengan yang satu ini.

Kembali ke browser web Anda, reload halaman indeks dan jika Anda login, Anda akan lihat mengedit dan menghapus link untuk setiap post. Jika tidak, Anda akan melihat apa-apa.

Sementara ini akan cukup jika Anda memiliki aplikasi dengan satu atau dua user, ini tidak cukup jika Anda memiliki pendaftaran terbuka.


Langkah 3: Memasang ACL

Buka Uses controller dan menambahkan komponen ACL.

Selanjutnya, mari kita membuat sebuah fungsi untuk menginstal ACO dan ARO node.

Dengan mengimpor ACL komponen, kita dapat mengakses ACO dan ARO model. Kita mulai dengan menciptakan ARO, yang bermaksud untuk objek; dengan kata lain, yang akan mengakses objek. Itu akan menjadi user (karena User string dalam model). Kami membuat role yang berbeda; Super, Admin, User dan Suspended.

Selanjutnya, kami melakukan hal yang sama dengan ACO, karena kita hanya memiliki dua objek untuk mengelola (Posts dan Uses), kita akan membuat dua, satu untuk masing-masing.

Sekarang, sebuah catatan singkat. Array yang kita simpan ACO maupun ARO memiliki empat bidang: nama model, foreign ket (yang berguna jika Anda ingin memberikan akses ke satu ARO, seperti post yang ia buat), parent id (yang akan digunakan kemudian dan hubungan parent-child node; kita akan membuat user di bawah role ini), dan alias (yang merupakan bentuk cepat untuk menemukan objek).

Akhirnya, kami menggunakan ACL's allow() fungsi. Parameter pertama adalah ACO alias; kedua, ARO alias, dan ketiga, permission yang diberikan kepada kata ARO. Superuser memiliki akses penuh ke pos dan user model, Admin memiliki akses penuh ke Post model, dan User dapat hanya membuat post.

Fungsi awal, saya deklarasi condition untuk memeriksa apakah peran Admin ada di ACO. Anda tidak ingin menginstal hal yang sama lebih dari sekali, kan? Itu akan mengacaukan database cukup buruk.

Buka /users/install di peramban web Anda, dan, karena kita tidak memiliki view, CakePHP akan melemparkan kesalahan, tapi hanya memeriksa MySQL dump. Semua relationship telah berhasil dibuat, sekarang saatnya untuk bekerja dengan child node.

Pengaturan pengguna untuk role

Mari kita membersihkan users table. Buka phpMyAdmin, pilih database Anda, tabel users dan klik empty. Kami akan kembali ke fungsi register() pada User Controller. Tepat di bawah baris ini:

Paste kode ini:

Dalam baris pertama kita membuat objek ARO baru. Kemudian kita akan mendapatkan parent notde di mana user akan dibuat. Jika ada data dalam database, kami akan menetapkan ke ARO user lain, user pertama harus Super.

Kemudian kami akan menyimpan ARO baru; model yang kami bekerja untuk saat ini, User, foreign_key adalah id record terakhir yang kami buat. parent_id adalah node kami mulai dengan; kami hanya akan melewati id dan akhirnya alias. Ini adalah ide yang baik untuk menyebutnya Model_name, maka pemisah::, dan kemudian identifier. Ini akan menjadi jauh lebih mudah untuk menemukan itu.

Sekarang kita sudah selesai. Membuat empat user: superuser, adminuser, normaluser dan suspendeduser. Saya sarankan sama username dan password untuk tujuan pengujian. Jangan lupa bahwa, sampai titik ini, hanya superuser memiliki peran Super; Semua yang tersisa akan menjadi User!


Langkah 4: Membaca Permission

Karena ACL komponen, ini dapat dicapai hanya dalam controller. Kemudian, itu akan juga dalam view; Tapi hal pertama pertama. Mencakup komponen ACL di controller posting, seperti yang kita lakukan di User controller. Sekarang Anda dapat mulai memeriksa permission. Mari kita pergi ke fungsi edit dan melakukan tes cepat. Dalam baris pertama dari metode mengatakan, menambahkan ini.

ACL's check() fungsi membutuhkan tiga parameter: ARO, ACO dan action. Pergi dan mengedit posting, dan, jika Anda tidak masuk sebagai super user, script akan mati. Pergi ke /users/login dan akses sebagai Super user dan kembali untuk mengedit. Anda dapat mengedit posting. Periksa di bawah MySQL dump untuk melihat keajaiban. Empat database query: itu pasti tidak terukur.

Kami memiliki dua isu. Pertama, dua baris untuk memeriksa izin. Kedua, ACLs tidak sedang dicached. Dan jangan lupa semua user yang login dapat melihat tautan edit, bahkan jika hanya Super user dapat menggunakannya.

Mari kita membuat komponen baru. Mari kita menyebutnya Access.

Menyimpannya dalam controllers/components sebagai access.php. Var $user class akan dimulai sebagai komponen dimuat, dan startup() merupakan fungsi callback, jadi sekarang sudah siap di kelas. Sekarang mari kita membuat fungsi check().

Metode check() kami akan memerlukan hanya dua parameter: ACO dan action (yang ini opsional). ARO akan menjadi pengguna saat ini untuk setiap sesi. Parameter action akan default ke *, yang merupakan akses penuh untuk ARO. Fungsi mulai dengan memeriksa jika $this->user tidak kosong (yang benar-benar mengatakan jika seorang user log in) dan kemudian kita pergi ke ACL. Kita sudah dibahas ini.

Kita sekarang dapat mencakup komponen Access di controller posting kami dan memeriksa permission dengan hanya satu baris.

Hasil yang sama dicapai dengan sedikit kode, tapi pesan kesalahan jelek. Anda lebih baik akan mengganti die() dengan error handler CakePHP:

Permission di views

Mungkin ini jelek, tetapi bekerja. Kita harus membuat sebuah helper yang memuat komponen dengan metode kustom untuk digunakan di helper.

Tambahkan fungsi ini dalam akses komponen (controllers/components/access.php).

Sekarang, mari kita menulis ulang access helper (views/helpers/access.php).

Metode beforeRender() adalah callback, mirip dengan komponen yang startup(). Kami yang memuat dua komponen dan karena ini akan digunakan dalam fungsi yang paling, itu adalah ide yang baik untuk memulai sekaligus, daripada untuk memulai mereka setiap kali metode yang disebut.

Sekarang Anda  index.ctp view di  views/posts Anda dapat mengganti baris ini.

Dengan yang satu ini.

Hanya jangan lupa untuk memeriksa permission, baik dalam view dan controller!

User data

Anda dapat mengakses user data untuk user yang login dengan metode user() pada komponen Auth. Kemudian Anda dapat mengakses array dan mendapatkan info yang Anda inginkan. Tapi harus ada cara yang lebih baik. Mari kita menambahkan fungsi berikut dalam komponen Access.

Hal ini sangat berguna ketika Anda perlu untuk menyimpan Post dengan user_id relationship.

Dan dalam view, kita dapat melakukan sesuatu yang serupa dengan helper.

Dalam template file Anda dapat melakukan sesuatu seperti di bawah ini untuk menyambut user berdasarkan namanya.


Langkah 5: Memodifikasi Permission

Mari kita mengatakan kita perlu beralih role bagi user #4: dia perlu Super User. Jadi, id user adalah 4 dan Aro's id adalah 1.

Sekarang kita perlu menemukan Aro User untuk memodifikasi parent Aro.

Akhirnya, jika variabel $aro_user tidak kosong, mari kita memperbarui bidang Aro.parent_id.

Harap dicatat bahwa Anda harus memvalidasi id user dan id aro baru. Jika salah satu dari ini tidak ada, itu akan membuat kekacauan di tabel ACL Anda.


Langkah 6: optimasi

Meskipun komponen yang kami hanya dibuat sederhana dan berguna, database kueri dengan setiap cek. Hal ini belum siap untuk production. Pertama, database harus di kueri sesedikit mungkin. Untuk mengoptimalkan ini, kita harus mengambil keuntungan dari CakePHP Cache.

Menggunakan Cache akan mengurangi beban cukup sedikit, tapi jika kita memiliki sepuluh posting muncul dalam index, dan, untuk masing-masing, kami akan memeriksa jika pengguna memiliki permission update posting Aco, framework akan membaca dan parsing file untuk mengembalikan hasil yang sama... sepuluh kali untuk setiap halaman load.

Itulah titik kedua: variabel di dalam kelas dan beberapa conditional akan membuat pekerjaan lebih ringan, sehingga permintaan berulang akan memeriksa terhadap Cache hanya sekali.

Kedua perubahan ini tercermin dalam access_cache.php, di dalam direktori controllers/components. Jadi pastikan Anda men-download sourcenya!


Kesimpulan

Access Control Lists adalah fitur dasar yang membutuhkan kebanyakan aplikasi. CakePHP memiliki implementasi yang bagus, tetapi tidak memiliki baik dokumentasi dan contoh-contoh. Saya berharap bahwa, dengan tutorial ini, dua isu ini akan sekarang ditutupi. Terima kasih sudah membaca!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.