Benutzerautorisierung
Benutzerautorisierung
- Einführung
- Geschrieben von Gates
- Richtlinie erstellen
- Strategie schreiben
- verwendet Richtlinien, um Aktionen zu autorisieren
Einführung
Zusätzlich zur Bereitstellung -of-the-box Zusätzlich zum Benutzerauthentifizierungsdienst bietet Laravel auch eine einfache Methode zur Handhabung von Benutzerautorisierungsaktionen. Wie die Benutzerauthentifizierung ist auch die Autorisierungsmethode von Laravel einfach. Es gibt zwei Hauptmethoden zur Durchführung der Autorisierung: Gates und Richtlinien.
Stellen Sie sich Gates und Strategien als Routing und Controller vor. Gates bieten eine einfache, auf Schließungen basierende Autorisierungsmethode, während Richtlinien Controllern ähneln und die Autorisierungsauthentifizierung implementieren, indem sie ihre Logik um ein bestimmtes Modell oder eine bestimmte Ressource gruppieren. Wir erkunden zuerst Tore und schauen uns dann Strategien an.
Beim Erstellen einer Anwendung müssen Sie sich nicht zwischen der ausschließlichen Verwendung von Gates oder der ausschließlichen Verwendung von Strategien entscheiden. Die meisten Anwendungen enthalten wahrscheinlich sowohl Gates als auch Richtlinien und funktionieren einwandfrei. Gates werden hauptsächlich an Orten verwendet, an denen Modelle und Ressourcen nicht miteinander verknüpft sind, z. B. beim Anzeigen des Administratorfensters. Im Gegensatz dazu sollten Strategien innerhalb eines bestimmten Modells oder einer bestimmten Ressource verwendet werden.
Tore
Gates schreiben
Gates ist eine Abschlussfunktion, die verwendet wird, um zu bestimmen, ob der Benutzer berechtigt ist, eine bestimmte Aktion auszuführen, und der typische Ansatz besteht darin,
in AppProvidersAuthServiceProvider
Gate
zu verwenden, um sie zu definieren . Gates Total Es empfängt eine Benutzerinstanz als ersten Parameter und kann optionale Parameter empfangen, z. B. verwandte Eloquent Modell:
/** * 注册任意用户认证、用户授权服务。 * * @return void */ public function boot(){ $this->registerPolicies(); Gate::define('update-post', function ($user, $post) { return $user->id == $post->user_id; }); }
Gates können auch mithilfe einer Rückrufzeichenfolge definiert werden, die der Controller-Methode ähnelt Class@method
Stil:
/** * 注册任意用户认证、用户授权服务。 * * @return void */ public function boot(){ $this->registerPolicies(); Gate::define('update-post', 'App\Policies\PostPolicy@update'); }
ResourceGates
You You Sie können auch die Methode resource
verwenden, um mehrere Gates gleichzeitig zu definieren Methode:
Gate::resource('posts', 'App\Policies\PostPolicy');
Die obige manuelle Definition hat die gleiche Wirkung wie die folgende Gate-Definition:
Gate::define('posts.view', 'App\Policies\PostPolicy@view'); Gate::define('posts.create', 'App\Policies\PostPolicy@create'); Gate::define('posts.update', 'App\Policies\PostPolicy@update'); Gate::define('posts.delete', 'App\Policies\PostPolicy@delete');
Standardmäßig sind view
, create
, update
und delete
Methode . Durch Übergabe eines Arrays als dritten Parameter an die Methode resource
. Sie können die Standardmethoden überschreiben oder ergänzen. Die Schlüssel des Arrays definieren die Namen der Funktionen und die Werte definieren die Namen der Methoden. Der folgende Code erstellt beispielsweise zwei neue Gate-Definitionen – posts.image
und posts.photo
:
Gate::resource('posts', 'PostPolicy', [ 'image' => 'updateImage', 'photo' => 'updatePhoto', ]);
Authorization Action
Wenn Sie Tore zum Autorisieren von Aktionen verwenden, sollten Sie allows
oder verwenden denies
Methode. Beachten Sie, dass der aktuell authentifizierte Benutzer nicht an diese Methoden übergeben werden muss. Laravel verarbeitet den authentifizierten Benutzer automatisch und übergibt ihn dann an die Gete-Closure-Funktion:
if (Gate::allows('update-post', $post)) { // 指定当前用户可以进行更新... } if (Gate::denies('update-post', $post)) { // 指定当前用户不能更新... }
Wenn Sie feststellen möchten, ob ein bestimmter Benutzer zum Zugriff auf eine Aktion autorisiert wurde, können Sie Gate
forUser
verwenden in der Fassade Methoden:
if (Gate::forUser($user)->allows('update-post', $post)) { // 用户可以更新... } if (Gate::forUser($user)->denies('update-post', $post)) { // 用户不能更新... }
Gate Interception Check
Manchmal möchten Sie vielleicht einem bestimmten Benutzer alle Fähigkeiten gewähren. Sie können also mit der Methode before
einen Rückruf definieren, der vor allen anderen Berechtigungsprüfungen ausgeführt wird:
Gate::before(function ($user, $ability) { if ($user->isSuperAdmin()) { return true; } });
Wenn die Rückrufmethode before
ein Ergebnis ungleich Null zurückgibt, wird das Ergebnis als Ergebnis behandelt des Schecks.
Mit der Methode after
können Sie einen Callback definieren, der nach jeder Berechtigungsprüfung ausgeführt wird. Sie können das Ergebnis der Autorisierungsprüfung jedoch nicht innerhalb der after
-Rückrufmethode ändern:
Gate::after(function ($user, $ability, $result, $arguments) { // });
Ähnlich wie bei der before
-Prüfung gilt: Wenn der after
-Rückruf ein Ergebnis ungleich Null zurückgibt, wird das Ergebnis angezeigt werden als Ergebnis der Prüfung behandelt.
Strategie erstellen
Richtlinie generieren
Eine Richtlinie ist eine Klasse, die die Autorisierungslogik in einem bestimmten Modell oder einer bestimmten Ressource organisiert. Wenn Ihre Anwendung beispielsweise ein Blog ist, verfügen Sie beim Erstellen oder Aktualisieren des Blogs möglicherweise über ein Post
-Modell und ein entsprechendes PostPolicy
, um Benutzeraktionen zu autorisieren.
Sie können den Befehl artisan 命令
artisan command in make:policy
artisan command verwenden, um die Strategie zu generieren. Die generierte Richtlinie wird im Verzeichnis app/Policies
abgelegt. Wenn dieses Verzeichnis in Ihrer Anwendung nicht vorhanden ist, generiert Laravel es automatisch für Sie: Der Befehl
php artisan make:policy PostPolicy
make:policy
generiert eine leere Strategieklasse. Wenn die Klasse, die Sie generieren möchten, grundlegende „CRUD“-Strategiemethoden enthält, können Sie beim Ausführen des Befehls die Option --model
angeben:
php artisan make:policy PostPolicy --model=Post
{tip} Alle Strategien werden über Laravels Dienst The weitergeleitet Der Container ermöglicht Ihnen zum Auflösen die Verwendung von Typhinweisen für alle erforderlichen Abhängigkeiten im Richtlinienkonstruktor und deren automatische Injektion.
Richtlinie registrieren
Sobald eine Richtlinie vorhanden ist, muss sie registriert werden. Das in der neuen Laravel-Anwendung enthaltene AuthServiceProvider
verfügt über ein policies
-Attribut, das verschiedene Modelle ihren Strategien zuordnet. Durch die Registrierung einer Richtlinie wird Laravel angewiesen, welche Richtlinie beim Autorisieren von Aktionen für den Zugriff auf ein bestimmtes Modell verwendet werden soll:
<?php namespace App\Providers; use App\Post;use App\Policies\PostPolicy; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider{ /** * 应用的策略映射。 * * @var array */ protected $policies = [ Post::class => PostPolicy::class, ]; /** * 注册任意应用认证、应用授权服务 * * @return void */ public function boot() { $this->registerPolicies(); // } }
Richtlinien werden automatisch erkannt
, solange das Modell und die Richtlinie folgen Standardmäßige Benennung von Laravel Per Konvention kann Laravel automatisch Strategien erkennen, anstatt Modellstrategien manuell zu registrieren. Insbesondere muss sich die Strategie im Verzeichnis Policies
unter dem Verzeichnis befinden, das das Modell enthält. So können beispielsweise Modelle im Verzeichnis app
und Strategien im Verzeichnis app/Policies
abgelegt werden. Darüber hinaus muss der Strategiename mit dem Modellnamen übereinstimmen und das Suffix Policy
haben. Daher entspricht das User
-Modell der UserPolicy
-Klasse.
Wenn Sie Ihre eigene Strategieerkennungslogik bereitstellen möchten, können Sie einen benutzerdefinierten Rückruf mit der Methode Gate :: guessPolicyNamesUsing
registrieren. Normalerweise sollte diese Methode von der AuthServiceProvider
-Methode der Anwendung aufgerufen werden: boot
use Illuminate\Support\Facades\Gate; Gate::guessPolicyNamesUsing(function ($modelClass) { // return policy class name... });
{note} Alle explizit inSchreibstrategiezugeordneten Richtlinien haben Vorrang vor automatisch erkannten Richtlinien.
AuthServiceProvider
Richtlinienmethoden
Sobald die Autorisierungsrichtlinie registriert ist, können Sie nach der Autorisierung Methoden für jede Aktion hinzufügen. Beispielsweise definieren wir in PostPolicy
eine update
-Methode, die bestimmt, ob die angegebene User
die angegebene Post
-Instanz aktualisieren kann. Die Methode
update
empfängt die Instanzen User
und Post
als Parameter und sollte true
oder false
zurückgeben, um anzugeben, ob der Benutzer berechtigt ist, das angegebene Post
zu aktualisieren. In diesem Beispiel müssen wir also feststellen, ob das id
des Benutzers mit dem user_id
im Beitrag übereinstimmt.
<?php namespace App\Policies;use App\User; use App\Post;class PostPolicy{ /** * 判断该方法能否被用户操作。 * * @param \App\User $user * @param \App\Post $post * @return bool */ public function update(User $user, Post $post) { return $user->id === $post->user_id; } }
Sie können weiterhin zusätzliche Methoden für diese Autorisierungsrichtlinie definieren. Sie können beispielsweise view
- oder delete
-Methoden definieren, um verschiedene Verhaltensweisen von Post
zu autorisieren, und Sie können der benutzerdefinierten Strategiemethode auch einen Namen geben, der Ihnen gefällt.
{tip} Wenn Sie beim Generieren einer Strategie in der Artisan-Konsole die Option
--model
verwenden, enthält diese die Aktionsmethodenview
,create
,update
unddelete
.
Enthält keine Modellmethoden
Einige Richtlinienmethoden empfangen stattdessen nur aktuell authentifizierte Benutzer als Parameter der Übergabe der berechtigungsbezogenen Modellinstanz. Das häufigste Anwendungsszenario ist die Autorisierung der Aktion create
. Wenn Sie beispielsweise einen Blog erstellen, möchten Sie möglicherweise zunächst prüfen, ob der aktuelle Benutzer die Berechtigung zum Erstellen eines Blogs hat.
Wenn Sie eine Strategiemethode definieren, die keine Übergabe einer Modellinstanz erfordert, wie z. B. die create
-Methode, erhält sie keine Modellinstanz als Parameter. Sie sollten diese Methode so definieren, dass nur autorisierte Benutzer als Parameter akzeptiert werden.
/** * 判断用户是否可以创建请求。 * * @param \App\User $user * @return bool */ public function create(User $user){ // }
Gastbenutzer
Standardmäßig gilt: Wenn eine eingehende HTTP-Anfrage nicht von einem authentifizierten Benutzer initiiert wird, dann Alle Tore und Strategien werden automatisch zurückgegeben false
. Sie können jedoch zulassen, dass diese Autorisierungsprüfungen in Ihre Gates und Richtlinien übernommen werden, indem Sie einen „optionalen“ Typhinweis deklarieren oder null
Standardwerte für Benutzerparameterdefinitionen bereitstellen:
<?php namespace App\Policies; use App\User;use App\Post;class PostPolicy{ /** * 判断用户是否能更新指定帖子。 * * @param \App\User $user * @param \App\Post $post * @return bool */ public function update(?User $user, Post $post) { return $user->id === $post->user_id; } }
Richtlinienfilter
Für einen bestimmten Benutzer möchten Sie möglicherweise alle Aktionen über eine bestimmte Richtlinie autorisieren. Um dies zu erreichen, definieren Sie eine before
-Methode in der Strategie. Die before
-Methode wird vor allen anderen Methoden in der Richtlinie ausgeführt und bietet somit eine Möglichkeit, andere Aktionen als die angegebene Richtlinienmethode zur Durchführung einer Beurteilung zu autorisieren. Das häufigste Szenario für diese Funktion besteht darin, dem Administrator der Anwendung Zugriff auf alle Aktionen zu gewähren:
public function before($user, $ability){ if ($user->isSuperAdmin()) { return true; } }
Wenn Sie einem Benutzer alle Berechtigungen verweigern möchten, sollten Sie before
in der Methode false
zurückgeben . Wenn der Rückgabewert null
ist, schlägt die Autorisierung bei dieser Strategie fehl.
{note} Die
before
-Methode einer Strategieklasse wird nicht aufgerufen, wenn die Klasse keine Methode enthält, die mit dem überprüften Funktionsnamen übereinstimmt.
Richtlinienautorisierungsaktion verwenden
Über Benutzermodell
Laravel Das integrierte User
-Modell enthält zwei nützliche Methoden zum Autorisieren von Aktionen: can
und cant
. Diese can
-Methode muss die autorisierte Aktion und das zugehörige Modell angeben. Um beispielsweise festzustellen, ob ein Benutzer berechtigt ist, ein bestimmtes Post
-Modell zu aktualisieren:
if ($user->can('update', $post)) { // }
Wenn die „Richtlinie registriert wurde“ für das angegebene Modell, die can
-Methode ruft automatisch die entsprechende Strategie auf und gibt einen booleschen Wert zurück. Wenn für dieses Modell keine Strategie registriert ist, versucht die Methode can
, ein abschlussbasiertes Gate aufzurufen, das dem angegebenen Aktionsnamen entspricht.
Aktionen, die keine Angabe eines Modells erfordern
Bedenken Sie, dass für einige Aktionen, wie z. B. create
, keine Angabe einer Modellinstanz erforderlich ist. Übergeben Sie in diesem Fall einen Klassennamen an die Methode can
. Dieser Klassenname wird verwendet, um zu bestimmen, welche Richtlinie zum Autorisieren der Aktion verwendet werden soll:
use App\Post;if ($user->can('create', Post::class)) { // 执行相关策略中的 "create" 方法... }
über die Middleware
Laravel enthält eine Middleware, die Aktionen autorisieren kann, bevor die Anfrage die Route oder den Controller erreicht. Standardmäßig ist die IlluminateAuthMiddlewareAuthorize
-Middleware dem AppHttpKernel
-Schlüssel in Ihrer can
-Klasse zugewiesen. Lassen Sie uns anhand eines Beispiels eines autorisierten Benutzers, der einen Blog aktualisiert, die Verwendung der can
-Middleware erläutern:
use App\Post;Route::put('/post/{post}', function (Post $post) { // 当前用户可以进行更新操作... })->middleware('can:update,post');
In diesem Beispiel haben wir zwei Parameter an die can
-Middleware übergeben. Der erste Parameter ist der Name der Aktion, die eine Autorisierung erfordert, und der zweite Parameter ist der Routing-Parameter, den wir an die Richtlinienmethode übergeben möchten. In diesem Fall verwenden wir „implizite Routenbindung“ und ein Post
-Modell wird an die Strategiemethode übergeben. Wenn der Benutzer nicht berechtigt ist, auf die angegebene Aktion zuzugreifen, generiert diese Middleware eine HTTP-Antwort mit dem Statuscode 403
.
Aktionen, die kein bestimmtes Modell erfordern
Ebenso erfordern einige Aktionen wie create
möglicherweise keine Modellinstanz. In diesem Fall können Sie der Middleware einen Klassennamen übergeben. Beim Autorisieren dieser Aktion wird dieser Klassenname verwendet, um zu bestimmen, welche Richtlinie verwendet werden soll:
Route::post('/post', function () { // 当前用户可以进行创建操作... })->middleware('can:create,App\Post');
über die Controller-Hilfsfunktion
Zusätzlich zur Bereitstellung von Hilfsmethoden im User
-Modell bietet Laravel auch Vererbung AppHttpControllersController
Diese Controller-Basisklasse bietet eine nützliche authorize
-Methode. Genau wie die Methode can
erfordert diese Methode die Aktion, die Sie autorisieren möchten, und das zugehörige Modell als Parameter. Wenn die Aktion nicht autorisiert ist, löst die authorize
-Methode eine IlluminateAuthAccessAuthorizationException
-Ausnahme aus und der Standard-Ausnahmehandler von Laravel wandelt diese Ausnahme in eine HTTP-Antwort mit einem 403
-Statuscode um.
<?php namespace App\Http\Controllers; use App\Post;use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新指定博客帖子。 * * @param Request $request * @param Post $post * @return Response * @throws \Illuminate\Auth\Access\AuthorizationException */ public function update(Request $request, Post $post) { $this->authorize('update', $post); // 当前用户可以更新博客... } }
Erfordert keine Angabe von Modellaktionen
Wie bereits erwähnt, erfordern einige Aktionen, wie z. B. create
, keine Angabe von Modellinstanzaktionen. In diesem Fall können Sie einen Klassennamen an die Methode authorize
übergeben. Beim Autorisieren dieser Aktion wird dieser Klassenname verwendet, um zu bestimmen, welche Richtlinie verwendet werden soll:
/** * 创建一个新的博客 * * @param Request $request * @return Response * @throws \Illuminate\Auth\Access\AuthorizationException */ public function create(Request $request){ $this->authorize('create', Post::class); // 当前用户可以新建博客... }
Ressourcencontroller autorisieren
Wenn Sie einen Ressourcencontroller verwenden, dann Sie kann die Methode authorizeResource
im Controller-Konstruktor verwenden. Diese Methode hängt die entsprechende can
-Middleware an die entsprechende Methode des Ressourcencontrollers an. Die Methode
authorizeResource
erhält als ersten Parameter den Namen der Vorlagenklasse und als zweiten Parameter den Namen des Routen-/Anfrageparameters, der die Modell-ID enthält:
<?php namespace App\Http\Controllers; use App\Post;use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PostController extends Controller{ public function __construct() { $this->authorizeResource(Post::class, 'post'); } }
{ Tipp} Sie können den Befehl
--model
mit der Optionmake:policy
verwenden, um schnell eine Strategieklasse basierend auf einem bestimmten Modell zu generieren::php artisan make:policy PostPolicy --model=Post
.
Über Blade-Vorlagen
Beim Schreiben von Blade-Vorlagen möchten Sie möglicherweise nur Teile davon angeben Seite Wird Benutzern angezeigt, die berechtigt sind, auf die angegebene Aktion zuzugreifen. Beispielsweise möchten Sie möglicherweise aktualisierte Formulare nur Benutzern anzeigen, die die Berechtigung zum Aktualisieren ihres Blogs haben. In solchen Fällen können Sie eine Reihe von Anweisungen wie @can
und @cannot
verwenden:
@can('update', $post) <!-- The Current User Can Update The Post --> @elsecan('create', App\Post::class) <!-- The Current User Can Create New Post --> @endcan @cannot('update', $post) <!-- The Current User Can't Update The Post --> @elsecannot('create', App\Post::class) <!-- The Current User Can't Create New Post --> @endcannot
Diese Anweisungen sind Abkürzungen zum Schreiben von @if
- und @unless
-Anweisungen. Die Anweisungen @can
und @cannot
werden jeweils in die folgenden Anweisungen umgewandelt:
@if (Auth::user()->can('update', $post)) <!-- The Current User Can Update The Post --> @endif @unless (Auth::user()->can('update', $post)) <!-- The Current User Can't Update The Post --> @endunless
Modellfreie Aktionen
Wie bei den meisten anderen Autorisierungsmethoden können Sie, wenn für die Aktion keine Modellinstanz erforderlich ist, einen Klassennamen an die Anweisungen @ can
und @ cannot
übergeben:
@can('create', App\Post::class) <!-- The Current User Can Create Posts --> @endcan @cannot('create', App\Post::class) <!-- The Current User Can't Create Posts --> @endcannot