Bouncer adalah pendekatan agnostik kerangka kerja yang elegan untuk mengelola peran dan kemampuan aplikasi apa pun menggunakan model Eloquent.
bouncer:clean
Bouncer adalah pendekatan agnostik kerangka kerja yang elegan untuk mengelola peran dan kemampuan aplikasi apa pun menggunakan model Eloquent. Dengan sintaksis yang ekspresif dan lancar, sebisa mungkin tidak mengganggu Anda: gunakan saat Anda mau, abaikan saat Anda tidak mau.
Untuk daftar sekilas fitur Bouncer, lihat lembar contekan.
Bouncer bekerja dengan baik dengan kemampuan lain yang telah Anda kodekan secara permanen di aplikasi Anda sendiri. Kode Anda selalu diutamakan: jika kode Anda mengizinkan suatu tindakan, Bouncer tidak akan ikut campur.
Setelah terinstal, Anda cukup memberi tahu penjaga pintu apa yang ingin Anda izinkan di gerbang:
// Give a user the ability to create posts
Bouncer:: allow ( $ user )-> to ( ' create ' , Post::class);
// Alternatively, do it through a role
Bouncer:: allow ( ' admin ' )-> to ( ' create ' , Post::class);
Bouncer:: assign ( ' admin ' )-> to ( $ user );
// You can also grant an ability only to a specific model
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Saat Anda memeriksa kemampuan di gerbang Laravel, Bouncer secara otomatis akan diajak berkonsultasi. Jika Bouncer melihat kemampuan yang telah diberikan kepada pengguna saat ini (baik secara langsung, atau melalui peran), Bouncer akan mengotorisasi pemeriksaan tersebut.
Catatan : Bouncer v1.0.2 memerlukan PHP 8.2+ dan Laravel/Eloquent 11+.
Jika Anda menggunakan Laravel v6-v10, gunakan Bouncer v1.0.1. Jika Anda menggunakan Laravel v5.5-v5.8, gunakan Bouncer RC6.
Instal Bouncer dengan komposer:
composer require silber/bouncer
Tambahkan sifat Bouncer ke model pengguna Anda:
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Sekarang, untuk menjalankan migrasi Bouncer. Publikasikan migrasi terlebih dahulu ke direktori migrations
aplikasi Anda, dengan menjalankan perintah berikut:
php artisan vendor:publish --tag="bouncer.migrations"
Terakhir, jalankan migrasi:
php artisan migrate
Setiap kali Anda menggunakan fasad Bouncer
dalam kode Anda, ingatlah untuk menambahkan baris ini ke impor namespace Anda di bagian atas file:
use Bouncer ;
Untuk informasi lebih lanjut tentang Laravel Facades, lihat dokumentasi Laravel.
Instal Bouncer dengan komposer:
composer require silber/bouncer
Siapkan database dengan komponen Eloquent Capsule:
use Illuminate Database Capsule Manager as Capsule ;
$ capsule = new Capsule ;
$ capsule -> addConnection ([ /* connection config */ ]);
$ capsule -> setAsGlobal ();
Lihat dokumentasi Eloquent Capsule untuk lebih jelasnya.
Jalankan migrasi dengan salah satu metode berikut:
Gunakan alat seperti vagabond untuk menjalankan migrasi Laravel di luar aplikasi Laravel. Anda akan menemukan migrasi yang diperlukan di file rintisan migrasi.
Alternatifnya, Anda bisa menjalankan SQL mentah langsung di database Anda.
Tambahkan sifat Bouncer ke model pengguna Anda:
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Buat instance Bouncer:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: create ();
// If you are in a request with a current user
// that you'd wish to check permissions for,
// pass that user to the "create" method:
$ bouncer = Bouncer:: create ( $ user );
Jika Anda menggunakan injeksi ketergantungan pada aplikasi, Anda dapat mendaftarkan instance Bouncer
sebagai singleton dalam container:
use Silber Bouncer Bouncer ;
use Illuminate Container Container ;
Container:: getInstance ()-> singleton (Bouncer::class, function () {
return Bouncer:: create ();
});
Anda sekarang dapat memasukkan Bouncer
ke kelas mana pun yang membutuhkannya.
Metode create
membuat instance Bouncer
dengan default yang masuk akal. Untuk menyesuaikannya sepenuhnya, gunakan metode make
untuk mendapatkan instance pabrik. Panggil create()
di pabrik untuk membuat instance Bouncer
:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: make ()
-> withCache ( $ customCacheInstance )
-> create ();
Lihat kelas Factory
untuk melihat semua penyesuaian yang tersedia.
Tetapkan model mana yang digunakan sebagai model pengguna di seluruh aplikasi Anda:
$ bouncer -> useUserModel (User::class);
Untuk konfigurasi tambahan, lihat bagian Konfigurasi di bawah.
Secara default, kueri Bouncer di-cache untuk permintaan saat ini. Untuk kinerja yang lebih baik, Anda mungkin ingin mengaktifkan cache lintas permintaan.
Menambahkan peran dan kemampuan kepada pengguna menjadi sangat mudah. Anda tidak harus membuat peran atau kemampuan terlebih dahulu. Cukup berikan nama peran/kemampuan, dan Bouncer akan membuatnya jika tidak ada.
Catatan: semua contoh di bawah ini menggunakan fasad
Bouncer
. Jika Anda tidak menggunakan fasad, Anda bisa memasukkan instanceSilberBouncerBouncer
ke dalam kelas Anda.
Mari buat peran bernama admin
dan berikan kemampuan untuk ban-users
dari situs kita:
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Itu saja. Di balik layar, Bouncer akan membuatkan Role
model dan Ability
model untuk Anda.
Jika Anda ingin menambahkan atribut tambahan ke peran/kemampuan, seperti judul yang dapat dibaca manusia, Anda bisa membuatnya secara manual menggunakan metode role
dan ability
di kelas Bouncer
:
$ admin = Bouncer:: role ()-> firstOrCreate ([
' name ' => ' admin ' ,
' title ' => ' Administrator ' ,
]);
$ ban = Bouncer:: ability ()-> firstOrCreate ([
' name ' => ' ban-users ' ,
' title ' => ' Ban users ' ,
]);
Bouncer:: allow ( $ admin )-> to ( $ ban );
Untuk sekarang memberikan peran admin
kepada pengguna, cukup beri tahu penjaga bahwa pengguna tersebut harus diberi peran admin:
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Alternatifnya, Anda dapat memanggil metode assign
langsung pada pengguna:
$ user -> assign ( ' admin ' );
Terkadang Anda mungkin ingin memberi pengguna kemampuan secara langsung, tanpa menggunakan peran:
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Di sini juga Anda dapat melakukan hal yang sama langsung dari pengguna:
$ user -> allow ( ' ban-users ' );
Terkadang Anda mungkin ingin membatasi kemampuan pada tipe model tertentu. Cukup berikan nama model sebagai argumen kedua:
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Jika Anda ingin membatasi kemampuan pada instance model tertentu, teruskan model sebenarnya:
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Gunakan metode toOwn
untuk memungkinkan pengguna mengelola model mereka sendiri :
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Sekarang, ketika memeriksa di gerbang apakah pengguna dapat melakukan tindakan pada postingan tertentu, user_id
postingan tersebut akan dibandingkan dengan id
pengguna yang login (ini dapat disesuaikan). Jika cocok, gerbang akan mengizinkan aksi tersebut.
Hal di atas akan memberikan semua kemampuan pada model "milik" pengguna. Anda dapat membatasi kemampuan dengan menindaklanjutinya dengan panggilan ke metode to
:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ( ' view ' );
// Or pass it an array of abilities:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ([ ' view ' , ' update ' ]);
Anda juga dapat mengizinkan pengguna untuk memiliki semua jenis model di aplikasi Anda:
Bouncer:: allow ( $ user )-> toOwnEverything ();
// And to restrict ownership to a given ability
Bouncer:: allow ( $ user )-> toOwnEverything ()-> to ( ' view ' );
Penjaga juga dapat mencabut peran yang telah ditetapkan sebelumnya dari pengguna:
Bouncer:: retract ( ' admin ' )-> from ( $ user );
Atau lakukan langsung pada pengguna:
$ user -> retract ( ' admin ' );
Penjaga juga dapat menghapus kemampuan yang sebelumnya diberikan kepada pengguna:
Bouncer:: disallow ( $ user )-> to ( ' ban-users ' );
Atau langsung pada pengguna:
$ user -> disallow ( ' ban-users ' );
Catatan: jika pengguna memiliki peran yang memungkinkan mereka untuk
ban-users
, mereka akan tetap memiliki kemampuan tersebut. Untuk melarangnya, hapus kemampuan dari peran tersebut atau tarik kembali peran tersebut dari pengguna.
Jika kemampuan telah diberikan melalui suatu peran, beri tahu penjaga untuk menghapus kemampuan dari peran tersebut:
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
Untuk menghapus kemampuan tipe model tertentu, masukkan namanya sebagai argumen kedua:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , Post::class);
Peringatan: jika pengguna memiliki kemampuan untuk
delete
instance$post
tertentu, kode di atas tidak akan menghapus kemampuan tersebut. Anda harus menghapus kemampuannya secara terpisah - dengan meneruskan$post
aktual sebagai argumen kedua - seperti yang ditunjukkan di bawah ini.
Untuk menghapus kemampuan instance model tertentu, teruskan model sebenarnya:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Catatan : metode
disallow
hanya menghapus kemampuan yang sebelumnya diberikan kepada pengguna/peran ini. Jika Anda ingin melarang sebagian dari apa yang diizinkan oleh kemampuan yang lebih umum, gunakan metodeforbid
.
Bouncer juga memungkinkan Anda untuk forbid
kemampuan tertentu, untuk kontrol yang lebih halus. Terkadang Anda mungkin ingin memberi pengguna/peran kemampuan yang mencakup berbagai tindakan, namun kemudian membatasi sebagian kecil dari tindakan tersebut.
Berikut beberapa contohnya:
Anda mungkin mengizinkan pengguna untuk melihat semua dokumen secara umum, namun memiliki dokumen tertentu yang sangat rahasia sehingga mereka tidak boleh melihatnya:
Bouncer:: allow ( $ user )-> to ( ' view ' , Document::class);
Bouncer:: forbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Anda mungkin ingin mengizinkan superadmin
Anda melakukan segala hal di aplikasi Anda, termasuk menambah/menghapus pengguna. Maka Anda mungkin memiliki peran admin
yang dapat melakukan segalanya selain mengelola pengguna:
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Anda mungkin ingin sesekali melarang pengguna, menghapus izin mereka untuk semua kemampuan. Namun, menghapus semua peran & kemampuan mereka berarti ketika larangan tersebut dihapus, kita harus mencari tahu apa peran dan kemampuan asli mereka.
Menggunakan kemampuan terlarang berarti mereka dapat mempertahankan semua peran dan kemampuan yang ada, namun tetap tidak diizinkan untuk melakukan apa pun. Kami dapat mencapai hal ini dengan membuat peran khusus banned
, yang mana kami akan melarang semuanya:
Bouncer:: forbid ( ' banned ' )-> everything ();
Lalu, kapan pun kami ingin mencekal pengguna, kami akan menetapkan peran banned
kepada mereka:
Bouncer:: assign ( ' banned ' )-> to ( $ user );
Untuk menghapus larangan tersebut, kami cukup mencabut peran dari pengguna:
Bouncer:: retract ( ' banned ' )-> from ( $ user );
Seperti yang Anda lihat, kemampuan terlarang Bouncer memberi Anda banyak kontrol terperinci atas izin di aplikasi Anda.
Untuk menghapus kemampuan terlarang, gunakan metode unforbid
:
Bouncer:: unforbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Catatan : ini akan menghapus semua kemampuan yang sebelumnya dilarang. Itu tidak akan secara otomatis mengizinkan kemampuan tersebut jika belum diizinkan oleh kemampuan reguler lain yang diberikan kepada pengguna/peran ini.
Catatan : Secara umum, Anda tidak perlu memeriksa peran secara langsung. Lebih baik mengizinkan suatu peran dengan kemampuan tertentu, lalu memeriksa kemampuan tersebut. Jika yang Anda butuhkan sangat umum, Anda bisa menciptakan kemampuan yang sangat luas. Misalnya, kemampuan
access-dashboard
selalu lebih baik daripada memeriksa peranadmin
ataueditor
secara langsung. Jika Anda jarang ingin memeriksa suatu peran, fungsi tersebut tersedia di sini.
Penjaga dapat memeriksa apakah pengguna memiliki peran tertentu:
Bouncer:: is ( $ user )-> a ( ' moderator ' );
Jika peran yang Anda periksa dimulai dengan huruf vokal, Anda mungkin ingin menggunakan metode an
:
Bouncer:: is ( $ user )-> an ( ' admin ' );
Sebaliknya, Anda juga dapat memeriksa apakah pengguna tidak memiliki peran tertentu:
Bouncer:: is ( $ user )-> notA ( ' moderator ' );
Bouncer:: is ( $ user )-> notAn ( ' admin ' );
Anda dapat memeriksa apakah pengguna memiliki salah satu dari banyak peran:
Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
Anda juga dapat memeriksa apakah pengguna memiliki semua peran yang diberikan:
Bouncer:: is ( $ user )-> all ( ' editor ' , ' moderator ' );
Anda juga dapat memeriksa apakah pengguna tidak memiliki peran tertentu:
Bouncer:: is ( $ user )-> notAn ( ' editor ' , ' moderator ' );
Pemeriksaan ini juga dapat dilakukan langsung pada pengguna:
$ user -> isAn ( ' admin ' );
$ user -> isA ( ' subscriber ' );
$ user -> isNotAn ( ' admin ' );
$ user -> isNotA ( ' subscriber ' );
$ user -> isAll ( ' editor ' , ' moderator ' );
Anda dapat menanyakan pengguna berdasarkan apakah mereka memiliki peran tertentu:
$ users = User:: whereIs ( ' admin ' )-> get ();
Anda juga dapat meneruskan beberapa peran, untuk menanyakan pengguna yang memiliki salah satu peran tertentu:
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
Untuk menanyakan pengguna yang memiliki semua peran tertentu, gunakan metode whereIsAll
:
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
Anda bisa mendapatkan semua peran untuk pengguna langsung dari model pengguna:
$ roles = $ user -> getRoles ();
Anda bisa mendapatkan semua kemampuan untuk pengguna langsung dari model pengguna:
$ abilities = $ user -> getAbilities ();
Ini akan mengembalikan kumpulan kemampuan yang diizinkan pengguna, termasuk kemampuan apa pun yang diberikan kepada pengguna melalui peran mereka.
Anda juga bisa mendapatkan daftar kemampuan yang secara eksplisit dilarang:
$ forbiddenAbilities = $ user -> getForbiddenAbilities ();
Otorisasi pengguna ditangani langsung di Gate
Laravel, atau pada model pengguna ( $user->can($ability)
).
Untuk kenyamanan, kelas Bouncer
menyediakan metode passthrough berikut:
Bouncer:: can ( $ ability );
Bouncer:: can ( $ ability , $ model );
Bouncer:: canAny ( $ abilities );
Bouncer:: canAny ( $ abilities , $ model );
Bouncer:: cannot ( $ ability );
Bouncer:: cannot ( $ ability , $ model );
Bouncer:: authorize ( $ ability );
Bouncer:: authorize ( $ ability , $ model );
Ini memanggil langsung ke metode setara mereka di kelas Gate
.
Bouncer tidak menambahkan arahan bilahnya sendiri. Karena Bouncer bekerja langsung dengan gerbang Laravel, cukup gunakan direktif @can
untuk memeriksa kemampuan pengguna saat ini:
@can ('update', $post)
< a href =" {{ route('post.update', $post) }} " > Edit Post </ a >
@endcan
Karena memeriksa peran secara langsung umumnya tidak disarankan, Bouncer tidak mengirimkan arahan terpisah untuk itu. Jika Anda masih bersikeras untuk memeriksa peran, Anda dapat melakukannya menggunakan arahan umum @if
:
@ if ( $ user -> isAn ( ' admin ' ))
//
@endif
Semua kueri yang dijalankan oleh Bouncer di-cache untuk permintaan saat ini. Jika Anda mengaktifkan cache lintas permintaan, cache akan tetap ada di berbagai permintaan.
Kapan pun diperlukan, Anda dapat menyegarkan cache penjaga sepenuhnya:
Bouncer:: refresh ();
Catatan: menyegarkan cache sepenuhnya untuk semua pengguna menggunakan tag cache jika tersedia. Tidak semua driver cache mendukung ini. Lihat dokumentasi Laravel untuk melihat apakah driver Anda mendukung tag cache. Jika driver Anda tidak mendukung tag cache, panggilan
refresh
mungkin sedikit lambat, tergantung pada jumlah pengguna di sistem Anda.
Alternatifnya, Anda dapat menyegarkan cache hanya untuk pengguna tertentu:
Bouncer:: refreshFor ( $ user );
Catatan : Saat menggunakan cakupan multi-tenancy, ini hanya akan menyegarkan cache untuk pengguna dalam konteks cakupan saat ini. Untuk menghapus data cache untuk pengguna yang sama dalam konteks cakupan yang berbeda, data tersebut harus dipanggil dari dalam cakupan tersebut.
Bouncer sepenuhnya mendukung aplikasi multi-penyewa, memungkinkan Anda mengintegrasikan peran dan kemampuan Bouncer dengan lancar untuk semua penyewa dalam aplikasi yang sama.
Untuk memulai, pertama-tama publikasikan middleware cakupan ke dalam aplikasi Anda:
php artisan vendor:publish --tag="bouncer.middleware"
Middleware sekarang akan dipublikasikan ke app/Http/Middleware/ScopeBouncer.php
. Middleware ini adalah tempat Anda memberi tahu Bouncer penyewa mana yang akan digunakan untuk permintaan saat ini. Misalnya, dengan asumsi semua pengguna Anda memiliki atribut account_id
, maka middleware Anda akan terlihat seperti ini:
public function handle ( $ request , Closure $ next )
{
$ tenantId = $ request -> user ()-> account_id ;
Bouncer:: scope ()-> to ( $ tenantId );
return $ next ( $ request );
}
Anda tentu saja bebas memodifikasi middleware ini agar sesuai dengan kebutuhan aplikasi Anda, seperti mengambil informasi penyewa dari subdomain, dll.
Sekarang dengan middleware sudah terpasang, pastikan untuk mendaftarkannya di Kernel HTTP Anda:
protected $ middlewareGroups = [
' web ' => [
// Keep the existing middleware here, and add this:
App Http Middleware ScopeBouncer::class,
]
];
Semua pertanyaan Bouncer kini akan dicakup ke penyewa tertentu.
Bergantung pada penyiapan aplikasi, Anda mungkin tidak ingin semua kueri dicakup ke penyewa saat ini. Misalnya, Anda mungkin memiliki serangkaian peran/kemampuan tetap yang sama untuk semua penyewa, dan hanya mengizinkan pengguna Anda mengontrol pengguna mana yang diberi peran tertentu, dan peran mana yang memiliki kemampuan tertentu. Untuk mencapai hal ini, Anda dapat memberi tahu cakupan Bouncer untuk hanya mencakup hubungan antara model Bouncer, namun tidak mencakup model itu sendiri:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ();
Selain itu, aplikasi Anda bahkan mungkin tidak mengizinkan penggunanya mengontrol kemampuan yang dimiliki peran tertentu. Dalam hal ini, beri tahu cakupan Bouncer untuk mengecualikan kemampuan peran dari cakupan tersebut, sehingga hubungan tersebut tetap bersifat global di semua penyewa:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ()-> dontScopeRoleAbilities ();
Jika kebutuhan Anda lebih terspesialisasi daripada yang diuraikan di atas, Anda dapat membuat Scope
Anda sendiri dengan logika khusus apa pun yang Anda perlukan:
use Silber Bouncer Contracts Scope ;
class MyScope implements Scope
{
// Whatever custom logic your app needs
}
Kemudian, di penyedia layanan, daftarkan cakupan kustom Anda:
Bouncer:: scope ( new MyScope );
Bouncer akan memanggil metode pada antarmuka Scope
di berbagai titik dalam pelaksanaannya. Anda bebas menanganinya sesuai dengan kebutuhan spesifik Anda.
Bouncer dikirimkan dengan default yang masuk akal, jadi seringkali konfigurasi apa pun tidak diperlukan. Untuk kontrol yang lebih detail, Bouncer dapat dikustomisasi dengan memanggil berbagai metode konfigurasi pada kelas Bouncer
.
Jika Anda hanya menggunakan satu atau dua opsi konfigurasi ini, Anda dapat menempelkannya ke metode boot
utama AppServiceProvider
Anda. Jika mereka mulai berkembang, Anda dapat membuat kelas BouncerServiceProvider
terpisah di direktori app/Providers
Anda (ingat untuk mendaftarkannya di susunan konfigurasi providers
).
Secara default, semua kueri yang dijalankan oleh Bouncer di-cache untuk permintaan saat ini. Untuk kinerja yang lebih baik, Anda mungkin ingin menggunakan cache lintas permintaan:
Bouncer:: cache ();
Peringatan: jika Anda mengaktifkan cache permintaan silang, Anda bertanggung jawab untuk menyegarkan cache setiap kali Anda membuat perubahan pada peran/kemampuan pengguna. Untuk cara merefresh cache, baca menyegarkan cache.
Sebaliknya, terkadang Anda mungkin ingin menonaktifkan cache sepenuhnya , bahkan dalam permintaan yang sama:
Bouncer:: dontCache ();
Hal ini sangat berguna dalam pengujian unit, ketika Anda ingin menjalankan pernyataan terhadap peran/kemampuan yang baru saja diberikan.
Untuk mengubah nama tabel database yang digunakan oleh Bouncer, teruskan array asosiatif ke metode tables
. Kuncinya harus berupa nama tabel default Bouncer, dan nilainya harus berupa nama tabel yang ingin Anda gunakan. Anda tidak harus memasukkan semua nama tabel; hanya yang ingin Anda ubah.
Bouncer:: tables ([
' abilities ' => ' my_abilities ' ,
' permissions ' => ' granted_abilities ' ,
]);
Migrasi yang dipublikasikan Bouncer menggunakan nama tabel dari konfigurasi ini, jadi pastikan Anda sudah menyiapkannya sebelum benar-benar menjalankan migrasi.
Anda dapat dengan mudah memperluas model Role
dan Ability
bawaan Bouncer:
namespace App Models ;
use Silber Bouncer Database Ability as BouncerAbility ;
class Ability extends BouncerAbility
{
// custom code
}
namespace App Models ;
use Silber Bouncer Database Role as BouncerRole ;
class Role extends BouncerRole
{
// custom code
}
Alternatifnya, Anda dapat menggunakan ciri IsAbility
dan IsRole
Bouncer tanpa benar-benar memperluas model Bouncer apa pun:
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsAbility ;
class Ability extends Model
{
use IsAbility;
// custom code
}
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsRole ;
class Role extends Model
{
use IsRole;
// custom code
}
Jika Anda menggunakan ciri-ciri tersebut alih-alih memperluas model Bouncer, pastikan untuk menyetel sendiri bidang $table
name dan $fillable
yang sesuai.
Apa pun metode yang Anda gunakan, langkah berikutnya adalah memberi tahu Bouncer untuk menggunakan model khusus Anda:
Bouncer:: useAbilityModel ( App Models Ability::class);
Bouncer:: useRoleModel ( App Models Role::class);
Catatan : Eloquent menentukan kunci asing suatu hubungan berdasarkan nama model induk (lihat dokumen Eloquent). Untuk mempermudah, beri nama kelas khusus Anda sama dengan Bouncer: masing-masing
Ability
danRole
.Jika Anda perlu menggunakan nama yang berbeda, pastikan untuk memperbarui file migrasi Anda atau mengganti metode hubungan untuk menyetel kunci asingnya secara eksplisit.
Secara default, Bouncer secara otomatis menggunakan model pengguna penjaga autentikasi default.
Jika Anda menggunakan Bouncer dengan pelindung non-default, dan menggunakan model pengguna yang berbeda, Anda harus memberi tahu Bouncer tentang model pengguna yang ingin Anda gunakan:
Bouncer:: useUserModel ( App Admin::class);
Di Bouncer, konsep kepemilikan digunakan untuk memungkinkan pengguna melakukan tindakan pada model yang mereka "miliki".
Secara default, Bouncer akan memeriksa user_id
model terhadap kunci utama pengguna saat ini. Jika diperlukan, ini dapat disetel ke atribut lain:
Bouncer:: ownedVia ( ' userId ' );
Jika model yang berbeda menggunakan kolom yang berbeda untuk kepemilikan, Anda dapat mendaftarkannya secara terpisah:
Bouncer:: ownedVia (Post::class, ' created_by ' );
Bouncer:: ownedVia (Order::class, ' entered_by ' );
Untuk kontrol yang lebih besar, Anda dapat meneruskan penutupan dengan logika khusus Anda:
Bouncer:: ownedVia (Game::class, function ( $ game , $ user ) {
return $ game -> team_id == $ user -> team_id ;
});
Ada beberapa konsep di Bouncer yang terus ditanyakan orang, berikut daftar singkat beberapa topik tersebut:
Penyemaian peran dan kemampuan awal dapat dilakukan di kelas seeder Laravel biasa. Mulailah dengan membuat file seeder khusus untuk Bouncer:
php artisan make:seeder BouncerSeeder
Tempatkan semua kode peran & kemampuan penyemaian Anda dalam metode run
seeder. Berikut ini contoh tampilannya:
use Bouncer ;
use Illuminate Database Seeder ;
class BouncerSeeder extends Seeder
{
public function run ()
{
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Bouncer:: allow ( ' editor ' )-> to ( ' create ' , Post::class);
Bouncer:: allow ( ' editor ' )-> toOwn (Post::class);
// etc.
}
}
Untuk benar-benar menjalankannya, teruskan nama kelas seeder ke opsi class
dari perintah db:seed
:
php artisan db:seed --class=BouncerSeeder
scope
Bouncer dapat digunakan untuk memisahkan bagian-bagian situs yang berbeda, membuat silo untuk masing-masing bagian dengan serangkaian peran & kemampuannya sendiri:
Buat middleware ScopeBouncer
yang menggunakan $identifier
dan menetapkannya sebagai cakupan saat ini:
use Bouncer , Closure ;
class ScopeBouncer
{
public function handle ( $ request , Closure $ next , $ identifier )
{
Bouncer:: scope ()-> to ( $ identifier );
return $ next ( $ request );
}
}
Daftarkan middleware baru ini sebagai middleware rute di kelas Kernel HTTP Anda:
protected $ routeMiddleware = [
// Keep the other route middleware, and add this:
' scope-bouncer ' => App Http Middleware ScopeBouncer::class,
];
Di penyedia layanan rute Anda, terapkan middleware ini dengan pengidentifikasi berbeda untuk rute publik dan rute dasbor:
Route:: middleware ([ ' web ' , ' scope-bouncer:1 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/public.php ' ));
Route:: middleware ([ ' web ' , ' scope-bouncer:2 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/dashboard.php ' ));
Itu saja. Semua peran dan kemampuan sekarang akan dicakup secara terpisah untuk setiap bagian situs Anda. Untuk menyempurnakan cakupan cakupan, lihat Menyesuaikan cakupan Bouncer.
Dimulai dengan Laravel 5.4, kumpulan karakter database default sekarang adalah utf8mb4
. Jika Anda menggunakan beberapa database versi lama (MySQL di bawah 5.7.7, atau MariaDB di bawah 10.2.2) dengan Laravel 5.4+, Anda akan mendapatkan kesalahan SQL saat mencoba membuat indeks pada kolom string. Untuk memperbaikinya, ubah panjang string default Laravel di AppServiceProvider
Anda :
use Illuminate Support Facades Schema ;
public function boot ()
{
Schema:: defaultStringLength ( 191 );
}
Anda dapat membaca lebih lanjut di artikel Berita Laravel ini.
Kolom JSON adalah tambahan yang relatif baru untuk MySQL (5.7.8) dan MariaDB (10.2.7). Jika Anda menggunakan versi database yang lebih lama, Anda tidak dapat menggunakan kolom JSON.
Solusi terbaik adalah memutakhirkan DB Anda. Jika saat ini hal tersebut tidak memungkinkan, Anda dapat mengubah file migrasi yang dipublikasikan untuk menggunakan kolom text
:
- $table->json('options')->nullable();
+ $table->text('options')->nullable();
bouncer:clean
Perintah bouncer:clean
menghapus kemampuan yang tidak digunakan. Menjalankan perintah ini akan menghapus 2 jenis kemampuan yang tidak digunakan:
Kemampuan yang tidak ditugaskan - kemampuan yang tidak diberikan kepada siapa pun. Misalnya:
Bouncer:: allow ( $ user )-> to ( ' view ' , Plan::class);
Bouncer:: disallow ( $ user )-> to ( ' view ' , Plan::class);
Pada titik ini, kemampuan "lihat rencana" tidak diberikan kepada siapa pun, sehingga akan dihapus.
Catatan : bergantung pada konteks aplikasi Anda, Anda mungkin tidak ingin menghapusnya. Jika Anda mengizinkan pengguna mengelola kemampuan di UI aplikasi, Anda mungkin tidak ingin menghapus kemampuan yang belum ditetapkan. Lihat di bawah.
Kemampuan yatim piatu - kemampuan model yang modelnya telah dihapus:
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ plan );
$ plan -> delete ();
Karena rencananya sudah tidak ada lagi, kemampuannya tidak lagi berguna, sehingga akan terhapus.
Jika Anda hanya ingin menghapus satu jenis kemampuan yang tidak digunakan, jalankan dengan salah satu tanda berikut:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
Jika Anda tidak memberikan tanda apa pun, itu akan menghapus kedua jenis kemampuan yang tidak digunakan.
Untuk menjalankan perintah ini secara berkala secara otomatis, tambahkan perintah ini ke jadwal kernel konsol Anda:
$ schedule -> command ( ' bouncer:clean ' )-> weekly ();
// Adding abilities for users
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: allow ( $ user )-> everything ();
Bouncer:: allow ( $ user )-> toManage (Post::class);
Bouncer:: allow ( $ user )-> toManage ( $ post );
Bouncer:: allow ( $ user )-> to ( ' view ' )-> everything ();
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Bouncer:: allow ( $ user )-> toOwnEverything ();
// Removing abilities uses the same syntax, e.g.
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: disallow ( $ user )-> toManage (Post::class);
Bouncer:: disallow ( $ user )-> toOwn (Post::class);
// Adding & removing abilities for roles
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
// You can also forbid specific abilities with the same syntax...
Bouncer:: forbid ( $ user )-> to ( ' delete ' , $ post );
// And also remove a forbidden ability with the same syntax...
Bouncer:: unforbid ( $ user )-> to ( ' delete ' , $ post );
// Re-syncing a user's abilities
Bouncer:: sync ( $ user )-> abilities ( $ abilities );
// Assigning & retracting roles from users
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Bouncer:: retract ( ' admin ' )-> from ( $ user );
// Assigning roles to multiple users by ID
Bouncer:: assign ( ' admin ' )-> to ([ 1 , 2 , 3 ]);
// Re-syncing a user's roles
Bouncer:: sync ( $ user )-> roles ( $ roles );
// Checking the current user's abilities
$ boolean = Bouncer:: can ( ' ban-users ' );
$ boolean = Bouncer:: can ( ' edit ' , Post::class);
$ boolean = Bouncer:: can ( ' delete ' , $ post );
$ boolean = Bouncer:: cannot ( ' ban-users ' );
$ boolean = Bouncer:: cannot ( ' edit ' , Post::class);
$ boolean = Bouncer:: cannot ( ' delete ' , $ post );
// Checking a user's roles
$ boolean = Bouncer:: is ( $ user )-> a ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> an ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> notA ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> notAn ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
$ boolean = Bouncer:: is ( $ user )-> all ( ' moderator ' , ' editor ' );
Bouncer:: cache ();
Bouncer:: dontCache ();
Bouncer:: refresh ();
Bouncer:: refreshFor ( $ user );
Beberapa fungsi ini juga tersedia langsung pada model pengguna:
$ user -> allow ( ' ban-users ' );
$ user -> allow ( ' edit ' , Post::class);
$ user -> allow ( ' delete ' , $ post );
$ user -> disallow ( ' ban-users ' );
$ user -> disallow ( ' edit ' , Post::class);
$ user -> disallow ( ' delete ' , $ post );
$ user -> assign ( ' admin ' );
$ user -> retract ( ' admin ' );
$ boolean = $ user -> isAn ( ' admin ' );
$ boolean = $ user -> isAn ( ' editor ' , ' moderator ' );
$ boolean = $ user -> isAll ( ' moderator ' , ' editor ' );
$ boolean = $ user -> isNotAn ( ' admin ' , ' moderator ' );
// Querying users by their roles
$ users = User:: whereIs ( ' superadmin ' )-> get ();
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
$ abilities = $ user -> getAbilities ();
$ forbidden = $ user -> getForbiddenAbilities ();
Di antara paket bajillion yang Spatie berikan dengan murah hati kepada komunitas, Anda akan menemukan paket izin laravel yang luar biasa. Seperti Bouncer, ini terintegrasi dengan baik dengan gerbang bawaan Laravel dan pemeriksaan izin, tetapi memiliki serangkaian pilihan desain yang berbeda dalam hal sintaksis, struktur & fitur DB.
Bouncer adalah perangkat lunak sumber terbuka yang dilisensikan di bawah lisensi MIT