Bouncer ist ein eleganter, Framework-unabhängiger Ansatz zur Verwaltung von Rollen und Fähigkeiten für jede App mithilfe von Eloquent-Modellen.
bouncer:clean
Bouncer ist ein eleganter, Framework-unabhängiger Ansatz zur Verwaltung von Rollen und Fähigkeiten für jede App mithilfe von Eloquent-Modellen. Mit einer ausdrucksstarken und flüssigen Syntax bleibt es Ihnen so weit wie möglich aus dem Weg: Verwenden Sie es, wann Sie möchten, und ignorieren Sie es, wenn Sie es nicht möchten.
Eine schnelle, übersichtliche Liste der Bouncer-Funktionen finden Sie im Spickzettel.
Bouncer funktioniert gut mit anderen Fähigkeiten, die Sie in Ihrer eigenen App fest codiert haben. Ihr Code hat immer Vorrang: Wenn Ihr Code eine Aktion zulässt, greift Bouncer nicht ein.
Nach der Installation können Sie dem Türsteher einfach mitteilen, was Sie am Tor zulassen möchten:
// 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 );
Wenn Sie die Fähigkeiten an Laravels Tor überprüfen, wird Bouncer automatisch zu Rate gezogen. Wenn Bouncer eine Fähigkeit sieht, die dem aktuellen Benutzer gewährt wurde (sei es direkt oder über eine Rolle), autorisiert er die Prüfung.
Hinweis : Bouncer v1.0.2 erfordert PHP 8.2+ und Laravel/Eloquent 11+.
Wenn Sie Laravel v6-v10 verwenden, verwenden Sie Bouncer v1.0.1. Wenn Sie Laravel v5.5-v5.8 verwenden, verwenden Sie Bouncer RC6.
Installieren Sie Bouncer mit Composer:
composer require silber/bouncer
Fügen Sie die Eigenschaft „Bouncer“ zu Ihrem Benutzermodell hinzu:
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Nun, um die Migrationen von Bouncer auszuführen. Veröffentlichen Sie zunächst die Migrationen im migrations
Ihrer App, indem Sie den folgenden Befehl ausführen:
php artisan vendor:publish --tag="bouncer.migrations"
Führen Sie abschließend die Migrationen aus:
php artisan migrate
Wenn Sie die Bouncer
Fassade in Ihrem Code verwenden, denken Sie daran, diese Zeile zu Ihren Namespace-Importen oben in der Datei hinzuzufügen:
use Bouncer ;
Weitere Informationen zu Laravel Facades finden Sie in der Laravel-Dokumentation.
Installieren Sie Bouncer mit Composer:
composer require silber/bouncer
Richten Sie die Datenbank mit der Eloquent Capsule-Komponente ein:
use Illuminate Database Capsule Manager as Capsule ;
$ capsule = new Capsule ;
$ capsule -> addConnection ([ /* connection config */ ]);
$ capsule -> setAsGlobal ();
Weitere Informationen finden Sie in der Eloquent Capsule-Dokumentation.
Führen Sie die Migrationen mit einer der folgenden Methoden aus:
Verwenden Sie ein Tool wie Vagabond, um Laravel-Migrationen außerhalb einer Laravel-App auszuführen. Die erforderlichen Migrationen finden Sie in der Migrations-Stub-Datei.
Alternativ können Sie das Roh-SQL direkt in Ihrer Datenbank ausführen.
Fügen Sie die Eigenschaft „Bouncer“ zu Ihrem Benutzermodell hinzu:
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Erstellen Sie eine Instanz von 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 );
Wenn Sie in Ihrer App die Abhängigkeitsinjektion verwenden, können Sie die Bouncer
-Instanz als Singleton im Container registrieren:
use Silber Bouncer Bouncer ;
use Illuminate Container Container ;
Container:: getInstance ()-> singleton (Bouncer::class, function () {
return Bouncer:: create ();
});
Sie können Bouncer
jetzt in jede Klasse einbauen, die es benötigt.
Die Methode create
erstellt eine Bouncer
-Instanz mit sinnvollen Standardeinstellungen. Um es vollständig anzupassen, verwenden Sie die Methode make
, um eine Factory-Instanz abzurufen. Rufen Sie create()
in der Factory auf, um die Bouncer
-Instanz zu erstellen:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: make ()
-> withCache ( $ customCacheInstance )
-> create ();
Schauen Sie sich die Factory
Klasse an, um alle verfügbaren Anpassungen zu sehen.
Legen Sie fest, welches Modell in Ihrer gesamten App als Benutzermodell verwendet wird:
$ bouncer -> useUserModel (User::class);
Weitere Informationen zur Konfiguration finden Sie im Abschnitt „Konfiguration“ unten.
Standardmäßig werden Bouncer-Abfragen für die aktuelle Anfrage zwischengespeichert. Für eine bessere Leistung möchten Sie möglicherweise das anforderungsübergreifende Caching aktivieren.
Das Hinzufügen von Rollen und Fähigkeiten zu Benutzern ist äußerst einfach. Sie müssen keine Rolle oder Fähigkeit im Voraus erstellen. Übergeben Sie einfach den Namen der Rolle/Fähigkeit und Bouncer erstellt sie, falls sie nicht vorhanden ist.
Hinweis: Die folgenden Beispiele verwenden alle die
Bouncer
Fassade. Wenn Sie keine Fassaden verwenden, können Sie stattdessen eine Instanz vonSilberBouncerBouncer
in Ihre Klasse einfügen.
Erstellen wir eine Rolle namens admin
und geben ihr die Möglichkeit, ban-users
:
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Das ist es. Hinter den Kulissen erstellt Bouncer sowohl ein Role
als auch ein Ability
für Sie.
Wenn Sie der Rolle/Fähigkeit zusätzliche Attribute hinzufügen möchten, beispielsweise einen für Menschen lesbaren Titel, können Sie diese mithilfe der role
und ability
der Bouncer
-Klasse manuell erstellen:
$ admin = Bouncer:: role ()-> firstOrCreate ([
' name ' => ' admin ' ,
' title ' => ' Administrator ' ,
]);
$ ban = Bouncer:: ability ()-> firstOrCreate ([
' name ' => ' ban-users ' ,
' title ' => ' Ban users ' ,
]);
Bouncer:: allow ( $ admin )-> to ( $ ban );
Um nun einem Benutzer die admin
zuzuweisen, teilen Sie dem Türsteher einfach mit, dass dem angegebenen Benutzer die Administratorrolle zugewiesen werden soll:
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Alternativ können Sie die assign
direkt beim Benutzer aufrufen:
$ user -> assign ( ' admin ' );
Manchmal möchten Sie einem Benutzer möglicherweise direkt eine Fähigkeit zuweisen, ohne eine Rolle zu verwenden:
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Auch hier können Sie dasselbe direkt vom Benutzer aus erreichen:
$ user -> allow ( ' ban-users ' );
Manchmal möchten Sie möglicherweise eine Funktion auf einen bestimmten Modelltyp beschränken. Übergeben Sie einfach den Modellnamen als zweites Argument:
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Wenn Sie die Möglichkeit auf eine bestimmte Modellinstanz beschränken möchten, übergeben Sie stattdessen das tatsächliche Modell:
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Verwenden Sie die toOwn
-Methode, um Benutzern die Verwaltung ihrer eigenen Modelle zu ermöglichen:
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Wenn nun am Gate überprüft wird, ob der Benutzer eine Aktion für einen bestimmten Beitrag ausführen darf, wird die user_id
des Beitrags mit der id
des angemeldeten Benutzers verglichen (dies kann angepasst werden). Wenn sie übereinstimmen, lässt das Tor die Aktion zu.
Dadurch werden alle Fähigkeiten für die „eigenen“ Modelle eines Benutzers gewährt. Sie können die Fähigkeiten einschränken, indem Sie anschließend die to
-Methode aufrufen:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ( ' view ' );
// Or pass it an array of abilities:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ([ ' view ' , ' update ' ]);
Sie können Benutzern auch erlauben, alle Arten von Modellen in Ihrer Anwendung zu besitzen:
Bouncer:: allow ( $ user )-> toOwnEverything ();
// And to restrict ownership to a given ability
Bouncer:: allow ( $ user )-> toOwnEverything ()-> to ( ' view ' );
Der Türsteher kann einem Benutzer auch eine zuvor zugewiesene Rolle entziehen:
Bouncer:: retract ( ' admin ' )-> from ( $ user );
Oder machen Sie es direkt beim Benutzer:
$ user -> retract ( ' admin ' );
Der Türsteher kann auch eine Fähigkeit entfernen, die einem Benutzer zuvor gewährt wurde:
Bouncer:: disallow ( $ user )-> to ( ' ban-users ' );
Oder direkt beim Benutzer:
$ user -> disallow ( ' ban-users ' );
Hinweis: Wenn der Benutzer eine Rolle hat, die es ihm erlaubt,
ban-users
zu verbieten, hat er diese Möglichkeit weiterhin. Um dies zu verbieten, entfernen Sie entweder die Fähigkeit aus der Rolle oder entziehen Sie dem Benutzer die Rolle.
Wenn die Fähigkeit durch eine Rolle gewährt wurde, weisen Sie den Türsteher stattdessen an, die Fähigkeit von der Rolle zu entfernen:
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
Um eine Fähigkeit für einen bestimmten Modelltyp zu entfernen, übergeben Sie ihren Namen als zweites Argument:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , Post::class);
Warnung: Wenn der Benutzer die Möglichkeit hat, eine bestimmte
$post
Instanz zudelete
, wird diese Fähigkeit durch den obigen Code nicht entfernt. Sie müssen die Fähigkeit separat entfernen – indem Sie den eigentlichen$post
als zweites Argument übergeben – wie unten gezeigt.
Um eine Fähigkeit für eine bestimmte Modellinstanz zu entfernen, übergeben Sie stattdessen das tatsächliche Modell:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Hinweis : Die
disallow
-Methode entfernt nur Fähigkeiten, die diesem Benutzer/dieser Rolle zuvor zugewiesen wurden. Wenn Sie eine Teilmenge dessen, was eine allgemeinere Fähigkeit erlaubt hat, verbieten möchten, verwenden Sie dieforbid
.
Mit Bouncer können Sie auch eine bestimmte Fähigkeit forbid
, um eine detailliertere Steuerung zu ermöglichen. Manchmal möchten Sie einem Benutzer/einer Rolle möglicherweise eine Fähigkeit gewähren, die ein breites Spektrum an Aktionen abdeckt, dann aber eine kleine Teilmenge dieser Aktionen einschränken.
Hier einige Beispiele:
Sie können einem Benutzer erlauben, generell alle Dokumente anzuzeigen, aber ein bestimmtes hochklassifiziertes Dokument haben, das er nicht anzeigen darf:
Bouncer:: allow ( $ user )-> to ( ' view ' , Document::class);
Bouncer:: forbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Möglicherweise möchten Sie Ihren superadmin
erlauben, alles in Ihrer App zu tun, einschließlich dem Hinzufügen/Entfernen von Benutzern. Dann verfügen Sie möglicherweise über eine admin
, die außer der Verwaltung von Benutzern alles andere tun kann:
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Möglicherweise möchten Sie Benutzer gelegentlich sperren und ihnen die Berechtigung für alle Fähigkeiten entziehen. Allerdings würde die tatsächliche Entfernung aller ihrer Rollen und Fähigkeiten bedeuten, dass wir nach der Aufhebung des Verbots herausfinden müssen, welche ursprünglichen Rollen und Fähigkeiten sie hatten.
Die Verwendung einer verbotenen Fähigkeit bedeutet, dass sie alle ihre bestehenden Rollen und Fähigkeiten behalten können, aber dennoch zu nichts berechtigt sind. Wir können dies erreichen, indem wir eine spezielle banned
Rolle erstellen, für die wir alles verbieten:
Bouncer:: forbid ( ' banned ' )-> everything ();
Wenn wir dann einen Benutzer sperren möchten, weisen wir ihm die banned
Rolle zu:
Bouncer:: assign ( ' banned ' )-> to ( $ user );
Um die Sperre aufzuheben, entziehen wir dem Benutzer einfach die Rolle:
Bouncer:: retract ( ' banned ' )-> from ( $ user );
Wie Sie sehen, geben Ihnen die verbotenen Fähigkeiten von Bouncer eine detaillierte Kontrolle über die Berechtigungen in Ihrer App.
Um eine verbotene Fähigkeit zu entfernen, verwenden Sie die unforbid
Methode:
Bouncer:: unforbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Hinweis : Dadurch werden alle zuvor verbotenen Fähigkeiten entfernt. Die Fähigkeit wird nicht automatisch zugelassen, wenn sie nicht bereits durch eine andere reguläre Fähigkeit zugelassen wird, die diesem Benutzer/dieser Rolle gewährt wird.
Hinweis : Im Allgemeinen sollten Sie die Rollen nicht direkt überprüfen müssen. Es ist besser, einer Rolle bestimmte Fähigkeiten zuzugestehen, statt stattdessen nach diesen Fähigkeiten zu suchen. Wenn Ihre Anforderungen sehr allgemein sind, können Sie sehr umfassende Fähigkeiten schaffen. Beispielsweise ist eine
access-dashboard
Funktion immer besser, als direkt nachadmin
odereditor
Rollen zu suchen. Für den seltenen Fall, dass Sie eine Rolle überprüfen möchten, steht diese Funktionalität hier zur Verfügung.
Der Türsteher kann prüfen, ob ein Benutzer eine bestimmte Rolle hat:
Bouncer:: is ( $ user )-> a ( ' moderator ' );
Wenn die Rolle, die Sie überprüfen, mit einem Vokal beginnt, möchten Sie möglicherweise die Methode an
alias verwenden:
Bouncer:: is ( $ user )-> an ( ' admin ' );
Umgekehrt können Sie auch prüfen, ob ein Benutzer keine bestimmte Rolle hat:
Bouncer:: is ( $ user )-> notA ( ' moderator ' );
Bouncer:: is ( $ user )-> notAn ( ' admin ' );
Sie können überprüfen, ob ein Benutzer eine von vielen Rollen hat:
Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
Sie können auch überprüfen, ob der Benutzer alle angegebenen Rollen hat:
Bouncer:: is ( $ user )-> all ( ' editor ' , ' moderator ' );
Sie können auch überprüfen, ob ein Benutzer keine der angegebenen Rollen hat:
Bouncer:: is ( $ user )-> notAn ( ' editor ' , ' moderator ' );
Diese Prüfungen können auch direkt beim Benutzer durchgeführt werden:
$ user -> isAn ( ' admin ' );
$ user -> isA ( ' subscriber ' );
$ user -> isNotAn ( ' admin ' );
$ user -> isNotA ( ' subscriber ' );
$ user -> isAll ( ' editor ' , ' moderator ' );
Sie können Ihre Benutzer danach abfragen, ob sie eine bestimmte Rolle haben:
$ users = User:: whereIs ( ' admin ' )-> get ();
Sie können auch mehrere Rollen übergeben, um Benutzer abzufragen, die eine der angegebenen Rollen haben:
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
Um Benutzer abzufragen, die über alle angegebenen Rollen verfügen, verwenden Sie die Methode whereIsAll
:
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
Sie können alle Rollen für einen Benutzer direkt aus dem Benutzermodell abrufen:
$ roles = $ user -> getRoles ();
Sie können alle Fähigkeiten für einen Benutzer direkt aus dem Benutzermodell abrufen:
$ abilities = $ user -> getAbilities ();
Dadurch wird eine Sammlung der zulässigen Fähigkeiten des Benutzers zurückgegeben, einschließlich aller Fähigkeiten, die dem Benutzer durch seine Rollen gewährt werden.
Sie können auch eine Liste der Fähigkeiten erhalten, die ausdrücklich verboten wurden:
$ forbiddenAbilities = $ user -> getForbiddenAbilities ();
Die Autorisierung von Benutzern erfolgt direkt am Laravel's Gate
oder im Benutzermodell ( $user->can($ability)
).
Der Einfachheit halber stellt die Bouncer
-Klasse die folgenden Passthrough-Methoden bereit:
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 );
Diese rufen direkt ihre entsprechenden Methoden in der Gate
-Klasse auf.
Bouncer fügt keine eigenen Blade-Anweisungen hinzu. Da Bouncer direkt mit Laravel's Gate arbeitet, verwenden Sie einfach seine @can
-Direktive, um die Fähigkeiten des aktuellen Benutzers zu überprüfen:
@can ('update', $post)
< a href =" {{ route('post.update', $post) }} " > Edit Post </ a >
@endcan
Da die direkte Suche nach Rollen im Allgemeinen nicht empfohlen wird, wird Bouncer hierfür nicht mit einer separaten Anweisung ausgeliefert. Wenn Sie dennoch darauf bestehen, nach Rollen zu suchen, können Sie dies mit der allgemeinen @if
-Direktive tun:
@ if ( $ user -> isAn ( ' admin ' ))
//
@endif
Alle von Bouncer ausgeführten Abfragen werden für die aktuelle Anforderung zwischengespeichert. Wenn Sie das anforderungsübergreifende Caching aktivieren, bleibt der Cache über verschiedene Anforderungen hinweg bestehen.
Bei Bedarf können Sie den Cache des Bouncers vollständig aktualisieren:
Bouncer:: refresh ();
Hinweis: Bei der vollständigen Aktualisierung des Caches für alle Benutzer werden Cache-Tags verwendet, sofern diese verfügbar sind. Dies wird nicht von allen Cache-Treibern unterstützt. Sehen Sie in der Dokumentation von Laravel nach, ob Ihr Treiber Cache-Tags unterstützt. Wenn Ihr Treiber keine Cache-Tags unterstützt, kann der Aufruf der
refresh
je nach Anzahl der Benutzer in Ihrem System etwas langsam sein.
Alternativ können Sie den Cache nur für einen bestimmten Benutzer aktualisieren:
Bouncer:: refreshFor ( $ user );
Hinweis : Bei Verwendung von Mandantenfähigkeitsbereichen wird dadurch nur der Cache für den Benutzer im Kontext des aktuellen Bereichs aktualisiert. Um zwischengespeicherte Daten für denselben Benutzer in einem anderen Bereichskontext zu löschen, müssen sie innerhalb dieses Bereichs aufgerufen werden.
Bouncer unterstützt vollständig mandantenfähige Apps, sodass Sie die Rollen und Fähigkeiten von Bouncer für alle Mandanten innerhalb derselben App nahtlos integrieren können.
Um zu beginnen, veröffentlichen Sie zunächst die Scope-Middleware in Ihrer App:
php artisan vendor:publish --tag="bouncer.middleware"
Die Middleware wird nun unter app/Http/Middleware/ScopeBouncer.php
veröffentlicht. Mit dieser Middleware teilen Sie Bouncer mit, welchen Mandanten er für die aktuelle Anfrage verwenden soll. Angenommen, Ihre Benutzer verfügen alle über ein account_id
Attribut, dann würde Ihre Middleware so aussehen:
public function handle ( $ request , Closure $ next )
{
$ tenantId = $ request -> user ()-> account_id ;
Bouncer:: scope ()-> to ( $ tenantId );
return $ next ( $ request );
}
Es steht Ihnen natürlich frei, diese Middleware an die Anforderungen Ihrer App anzupassen, z. B. die Mandanteninformationen aus einer Subdomain usw. abzurufen.
Nachdem Sie die Middleware installiert haben, müssen Sie sie unbedingt in Ihrem HTTP-Kernel registrieren:
protected $ middlewareGroups = [
' web ' => [
// Keep the existing middleware here, and add this:
App Http Middleware ScopeBouncer::class,
]
];
Alle Abfragen von Bouncer werden nun auf den angegebenen Mandanten beschränkt.
Abhängig von der Einrichtung Ihrer App möchten Sie möglicherweise nicht, dass alle Abfragen auf den aktuellen Mandanten beschränkt sind. Beispielsweise verfügen Sie möglicherweise über einen festen Satz von Rollen/Fähigkeiten, die für alle Mandanten gleich sind, und ermöglichen Ihren Benutzern lediglich die Steuerung, welchen Benutzern welche Rollen zugewiesen werden und welche Rollen über welche Fähigkeiten verfügen. Um dies zu erreichen, können Sie den Bouncer-Bereich anweisen, nur die Beziehungen zwischen den Bouncer-Modellen, nicht jedoch die Modelle selbst, zu berücksichtigen:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ();
Darüber hinaus ermöglicht Ihre App den Benutzern möglicherweise nicht einmal die Kontrolle über die Fähigkeiten einer bestimmten Rolle. In diesem Fall weisen Sie den Bouncer-Bereich an, Rollenfähigkeiten aus dem Bereich auszuschließen, damit diese Beziehungen über alle Mandanten hinweg global bleiben:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ()-> dontScopeRoleAbilities ();
Wenn Ihre Anforderungen noch spezieller sind als oben beschrieben, können Sie Ihren eigenen Scope
mit der von Ihnen benötigten benutzerdefinierten Logik erstellen:
use Silber Bouncer Contracts Scope ;
class MyScope implements Scope
{
// Whatever custom logic your app needs
}
Registrieren Sie dann bei einem Dienstanbieter Ihren benutzerdefinierten Bereich:
Bouncer:: scope ( new MyScope );
Bouncer ruft die Methoden auf der Scope
-Schnittstelle an verschiedenen Stellen seiner Ausführung auf. Es steht Ihnen frei, sie entsprechend Ihren spezifischen Bedürfnissen zu handhaben.
Der Bouncer wird mit sinnvollen Standardeinstellungen ausgeliefert, sodass in den meisten Fällen keine Konfiguration erforderlich sein sollte. Für eine detailliertere Steuerung kann Bouncer durch den Aufruf verschiedener Konfigurationsmethoden für die Bouncer
-Klasse angepasst werden.
Wenn Sie nur eine oder zwei dieser Konfigurationsoptionen verwenden, können Sie sie in die boot
Ihres Haupt- AppServiceProvider
einfügen. Wenn sie zu wachsen beginnen, können Sie eine separate BouncerServiceProvider
Klasse in Ihrem app/Providers
Verzeichnis erstellen (denken Sie daran, sie im providers
Konfigurationsarray zu registrieren).
Standardmäßig werden alle von Bouncer ausgeführten Abfragen für die aktuelle Anforderung zwischengespeichert. Für eine bessere Leistung können Sie Cross-Request-Caching verwenden:
Bouncer:: cache ();
Warnung: Wenn Sie das anforderungsübergreifende Caching aktivieren, sind Sie dafür verantwortlich, den Cache zu aktualisieren, wenn Sie Änderungen an den Rollen/Fähigkeiten des Benutzers vornehmen. Informationen zum Aktualisieren des Caches finden Sie unter Aktualisieren des Caches.
Im Gegenteil, Sie möchten möglicherweise manchmal den Cache vollständig deaktivieren , sogar innerhalb derselben Anfrage:
Bouncer:: dontCache ();
Dies ist besonders nützlich bei Unit-Tests, wenn Sie Behauptungen gegen Rollen/Fähigkeiten ausführen möchten, die gerade gewährt wurden.
Um die von Bouncer verwendeten Datenbanktabellennamen zu ändern, übergeben Sie ein assoziatives Array an die tables
. Die Schlüssel sollten die Standardtabellennamen von Bouncer sein und die Werte sollten die Tabellennamen sein, die Sie verwenden möchten. Sie müssen nicht alle Tabellennamen übergeben. nur diejenigen, die Sie ändern möchten.
Bouncer:: tables ([
' abilities ' => ' my_abilities ' ,
' permissions ' => ' granted_abilities ' ,
]);
Die veröffentlichte Migration von Bouncer verwendet die Tabellennamen aus dieser Konfiguration. Stellen Sie daher sicher, dass diese vorhanden sind, bevor Sie die Migration tatsächlich ausführen.
Sie können die integrierten Role
und Ability
von Bouncer problemlos erweitern:
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
}
Alternativ können Sie die Merkmale IsAbility
und IsRole
von Bouncer verwenden, ohne eines der Bouncer-Modelle tatsächlich zu erweitern:
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
}
Wenn Sie die Merkmale verwenden, anstatt die Bouncer-Modelle zu erweitern, stellen Sie sicher, dass Sie selbst den richtigen $table
Namen und $fillable
-Felder festlegen.
Unabhängig davon, welche Methode Sie verwenden, besteht der nächste Schritt darin, Bouncer tatsächlich anzuweisen, Ihre benutzerdefinierten Modelle zu verwenden:
Bouncer:: useAbilityModel ( App Models Ability::class);
Bouncer:: useRoleModel ( App Models Role::class);
Hinweis : Eloquent bestimmt den Fremdschlüssel von Beziehungen basierend auf dem Namen des übergeordneten Modells (siehe die Eloquent-Dokumente). Der Einfachheit halber benennen Sie Ihre benutzerdefinierten Klassen genauso wie die von Bouncer:
Ability
bzw.Role
.Wenn Sie unterschiedliche Namen verwenden müssen, aktualisieren Sie unbedingt entweder Ihre Migrationsdatei oder überschreiben Sie die Beziehungsmethoden, um deren Fremdschlüssel explizit festzulegen.
Standardmäßig verwendet Bouncer automatisch das Benutzermodell des Standard-Authentifizierungsschutzes.
Wenn Sie Bouncer mit einem nicht standardmäßigen Schutz verwenden und dieser ein anderes Benutzermodell verwendet, sollten Sie Bouncer über das Benutzermodell informieren, das Sie verwenden möchten:
Bouncer:: useUserModel ( App Admin::class);
In Bouncer wird das Eigentumskonzept verwendet, um Benutzern die Durchführung von Aktionen an Modellen zu ermöglichen, die ihnen „besitzen“.
Standardmäßig vergleicht Bouncer die user_id
des Modells mit dem Primärschlüssel des aktuellen Benutzers. Bei Bedarf kann dies auf ein anderes Attribut gesetzt werden:
Bouncer:: ownedVia ( ' userId ' );
Wenn verschiedene Modelle unterschiedliche Spalten für den Besitz verwenden, können Sie diese separat registrieren:
Bouncer:: ownedVia (Post::class, ' created_by ' );
Bouncer:: ownedVia (Order::class, ' entered_by ' );
Für eine bessere Kontrolle können Sie einen Abschluss mit Ihrer benutzerdefinierten Logik übergeben:
Bouncer:: ownedVia (Game::class, function ( $ game , $ user ) {
return $ game -> team_id == $ user -> team_id ;
});
Es gibt einige Konzepte in Bouncer, nach denen die Leute immer wieder fragen. Hier ist eine kurze Liste einiger dieser Themen:
Das Setzen der ersten Rollen und Fähigkeiten kann in einem regulären Laravel-Seeder-Kurs erfolgen. Erstellen Sie zunächst eine spezifische Seeder-Datei für Bouncer:
php artisan make:seeder BouncerSeeder
Platzieren Sie Ihren gesamten Seeding-Rollen- und Fähigkeitscode in der run
Methode des Seeders. Hier ist ein Beispiel, wie das aussehen könnte:
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.
}
}
Um es tatsächlich auszuführen, übergeben Sie den Klassennamen des Seeders an die class
des Befehls db:seed
:
php artisan db:seed --class=BouncerSeeder
scope
von Bouncer kann verwendet werden, um verschiedene Teile der Website abzutrennen und für jeden von ihnen ein Silo mit eigenen Rollen und Fähigkeiten zu erstellen:
Erstellen Sie eine ScopeBouncer
Middleware, die einen $identifier
annimmt und ihn als aktuellen Bereich festlegt:
use Bouncer , Closure ;
class ScopeBouncer
{
public function handle ( $ request , Closure $ next , $ identifier )
{
Bouncer:: scope ()-> to ( $ identifier );
return $ next ( $ request );
}
}
Registrieren Sie diese neue Middleware als Routen-Middleware in Ihrer HTTP-Kernel-Klasse:
protected $ routeMiddleware = [
// Keep the other route middleware, and add this:
' scope-bouncer ' => App Http Middleware ScopeBouncer::class,
];
Wenden Sie bei Ihrem Routendienstanbieter diese Middleware mit einer anderen Kennung für die öffentlichen Routen bzw. die Dashboard-Routen an:
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 ' ));
Das ist es. Alle Rollen und Fähigkeiten werden nun für jeden Abschnitt Ihrer Website separat festgelegt. Informationen zur Feinabstimmung des Umfangs des Bereichs finden Sie unter Anpassen des Bouncer-Bereichs.
Ab Laravel 5.4 ist der Standard-Datenbankzeichensatz nun utf8mb4
. Wenn Sie ältere Versionen einiger Datenbanken (MySQL unter 5.7.7 oder MariaDB unter 10.2.2) mit Laravel 5.4+ verwenden, erhalten Sie einen SQL-Fehler, wenn Sie versuchen, einen Index für eine Zeichenfolgenspalte zu erstellen. Um dies zu beheben, ändern Sie die Standardzeichenfolgenlänge von Laravel in Ihrem AppServiceProvider
:
use Illuminate Support Facades Schema ;
public function boot ()
{
Schema:: defaultStringLength ( 191 );
}
Weitere Informationen finden Sie in diesem Laravel News-Artikel.
JSON-Spalten sind eine relativ neue Ergänzung zu MySQL (5.7.8) und MariaDB (10.2.7). Wenn Sie eine ältere Version dieser Datenbanken verwenden, können Sie keine JSON-Spalten verwenden.
Die beste Lösung wäre ein Upgrade Ihrer Datenbank. Wenn dies derzeit nicht möglich ist, können Sie Ihre veröffentlichte Migrationsdatei so ändern, dass stattdessen eine text
verwendet wird:
- $table->json('options')->nullable();
+ $table->text('options')->nullable();
bouncer:clean
Der Befehl bouncer:clean
löscht ungenutzte Fähigkeiten. Durch die Ausführung dieses Befehls werden zwei Arten ungenutzter Fähigkeiten gelöscht:
Nicht zugewiesene Fähigkeiten – Fähigkeiten, die niemandem zugewiesen sind. Zum Beispiel:
Bouncer:: allow ( $ user )-> to ( ' view ' , Plan::class);
Bouncer:: disallow ( $ user )-> to ( ' view ' , Plan::class);
Zu diesem Zeitpunkt ist die Funktion „Pläne anzeigen“ niemandem zugewiesen und wird daher gelöscht.
Hinweis : Abhängig vom Kontext Ihrer App möchten Sie diese möglicherweise nicht löschen. Wenn Sie Ihren Benutzern erlauben, Fähigkeiten in der Benutzeroberfläche Ihrer App zu verwalten, möchten Sie wahrscheinlich keine nicht zugewiesenen Fähigkeiten löschen. Siehe unten.
Verwaiste Fähigkeiten – Modellfähigkeiten, deren Modelle gelöscht wurden:
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ plan );
$ plan -> delete ();
Da der Plan nicht mehr existiert, ist die Fähigkeit nicht mehr von Nutzen und wird daher gelöscht.
Wenn Sie nur einen Typ ungenutzter Fähigkeit löschen möchten, führen Sie ihn mit einem der folgenden Flags aus:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
Wenn Sie ihm keine Flags übergeben, werden beide Arten ungenutzter Fähigkeiten gelöscht.
Um diesen Befehl regelmäßig automatisch auszuführen, fügen Sie ihn dem Zeitplan Ihres Konsolenkernels hinzu:
$ 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 );
Einige dieser Funktionen sind auch direkt im Benutzermodell verfügbar:
$ 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 ();
Unter den Bajillion-Paketen, die Spatie der Community so großzügig zur Verfügung gestellt hat, finden Sie das ausgezeichnete Laravel-Permission-Paket. Wie Bouncer lässt es sich gut in die integrierten Gate- und Berechtigungsprüfungen von Laravel integrieren, verfügt jedoch über andere Designoptionen, wenn es um Syntax, DB-Struktur und Funktionen geht.
Bouncer ist eine Open-Source-Software, die unter der MIT-Lizenz lizenziert ist