Authorizing Actions Using Policies
Via The User Model
Das User-Modell, das Ihrer Laravel-Anwendung beiliegt, enthält zwei hilfreiche Methoden zur Autorisierung von Aktionen: can und cant. Die Dosenmethode erhält die Aktion, die Sie autorisieren möchten, und das entsprechende Modell. Lassen Sie uns zum Beispiel feststellen, ob ein Benutzer berechtigt ist, ein bestimmtes Post-Modell zu aktualisieren:
if ($user->can('update', $post)) {
//
}
Wenn eine Richtlinie für das gegebene Modell registriert ist, ruft die can-Methode automatisch die entsprechende Richtlinie auf und gibt das boolesche Ergebnis zurück. Wenn keine Richtlinie für das Modell registriert ist, versucht die can-Methode, das auf dem Abschluss basierende Gate aufzurufen, das dem gegebenen Aktionsnamen entspricht.
Actions That Don't Require Models
Denken Sie daran, dass für einige Aktionen wie z.B. das Erstellen von Dokumenten keine Modellinstanz erforderlich ist. In diesen Situationen können Sie der can-Methode einen Klassennamen übergeben. Der Klassenname wird verwendet, um zu bestimmen, welche Richtlinie bei der Autorisierung der Aktion verwendet werden soll:
use App\Post;
if ($user->can('create', Post::class)) {
// Executes the "create" method on the relevant policy...
}
Via Middleware
Laravel enthält eine Middleware, die Aktionen autorisieren kann, bevor die eingehende Anfrage überhaupt Ihre Routen oder Controller erreicht. Standardmäßig wird der Illuminate\Auth\Middleware\Authorize-Middleware der Key can in Ihrer Klasse App\Http\Kernel zugewiesen. Betrachten wir ein Beispiel für die Verwendung der can-Middleware, um zu autorisieren, dass ein Benutzer einen Blog-Beitrag aktualisieren kann:
use App\Post;
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');
In diesem Beispiel übergeben wir der can-Middleware zwei Argumente. Der erste ist der Name der Aktion, die wir autorisieren möchten, und das zweite ist der Routenparameter, den wir an die Richtlinienmethode übergeben möchten. Da wir in diesem Fall eine implizite Modellbindung verwenden, wird ein Post-Modell an die Richtlinienmethode übergeben. Wenn der Benutzer nicht berechtigt ist, die gegebene Aktion auszuführen, wird von der Middleware eine HTTP-Antwort mit einem 403-Statuscode generiert.
Actions That Don't Require Models
Auch hier gilt, dass für einige Aktionen, wie z.B. das create, keine Modellinstanz erforderlich ist. In diesen Situationen können Sie einen Klassennamen an die Middleware übergeben. Der Klassenname wird verwendet, um zu bestimmen, welche Richtlinie bei der Autorisierung der Aktion verwendet werden soll:
Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Post');
Via Controller Helpers
Zusätzlich zu den hilfreichen Methoden, die dem user-Modell zur Verfügung gestellt werden, bietet Laravel eine hilfreiche Autorisierungsmethode für jeden Ihrer Controller, die die Basisklasse der App\Http\Controller\Controller erweitern. Wie die can-Methode akzeptiert diese Methode den Namen der Aktion, die Sie autorisieren möchten, und das entsprechende Modell. Wenn die Aktion nicht autorisiert ist, wirft die Autorisierungsmethode eine Illuminate\Auth\Access\AuthorizationException, die der Standard-Laravel-Exception-Handler in eine HTTP-Antwort mit einem 403-Statuscode konvertiert:
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Update the given blog post.
*
* @param Request $request
* @param Post $post
* @return Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// The current user can update the blog post...
}
}
Actions That Don't Require Models
Wie bereits erwähnt, erfordern einige Aktionen wie z.B. das Create von Dokumenten keine Modellinstanz. In diesen Situationen sollten Sie der authorize-Methode einen Klassennamen übergeben. Der Klassenname wird verwendet, um zu bestimmen, welche Richtlinie bei der Autorisierung der Aktion verwendet werden soll:
/**
* Create a new blog post.
*
* @param Request $request
* @return Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create(Request $request)
{
$this->authorize('create', Post::class);
// The current user can create blog posts...
}
Authorizing Resource Controllers
Wenn Sie Ressourcen-Controller verwenden, können Sie die authorizeResource-Methode im Konstruktor des Controllers verwenden. Diese Methode hängt die entsprechenden Can-Middleware-Definitionen an die Methoden des Ressourcen-Controllers an.
Die authorizeResource-Methode akzeptiert den Klassennamen des Modells als erstes Argument und den Namen des Leitweg-/Anforderungsparameters, der die ID des Modells enthält, als zweites Argument:
<?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');
}
}
Die folgenden Controller-Methoden werden auf ihre entsprechende Richtlinienmethode abgebildet:
Controller Method |
Policy Method |
show |
view |
create |
create |
store |
create |
edit |
update |
update |
update |
destroy |
delete |
Sie können den Befehl make:policy mit der Option --model verwenden, um schnell eine Policy-Klasse für ein bestimmtes Modell zu generieren: php artisan make:policy PostPolicy --model=Post.
Via Blade Templates
Wenn Sie Blade-Vorlagen schreiben, möchten Sie möglicherweise einen Teil der Seite nur dann anzeigen, wenn der Benutzer zur Ausführung einer bestimmten Aktion berechtigt ist. Sie möchten z.B. ein Aktualisierungsformular für einen Blog-Beitrag nur dann anzeigen, wenn der Benutzer den Beitrag tatsächlich aktualisieren kann. In dieser Situation können Sie die @can- und @cannot-Richtlinienfamilie 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 Direktiven sind bequeme Abkürzungen für das Schreiben von @if- und @unless-Anweisungen. Die obigen @can- und @cannot-Anweisungen lassen sich jeweils in die folgenden Anweisungen übersetzen:
@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
Sie können auch bestimmen, ob ein Benutzer eine Berechtigungsfähigkeit aus einer bestimmten Liste von Fähigkeiten hat. Verwenden Sie dazu die @canany-Direktive:
@canany(['update', 'view', 'delete'], $post)
// The current user can update, view, or delete the post
@elsecanany(['create'], \App\Post::class)
// The current user can create a post
@endcanany
Actions That Don't Require Models
Wie bei den meisten anderen Berechtigungsmethoden können Sie einen Klassennamen an die Anweisungen @can und @cannot übergeben, wenn die Aktion keine Modellinstanz erfordert:
@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