aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webentwicklung

Laravel-Autorisierung: Policy- und Gate-Leitfaden

Ein Benutzer soll seinen eigenen Beitrag bearbeiten können, aber nicht den eines anderen; ein Redakteur soll Kommentare löschen können, ein gewöhnliches Mitglied jedoch nicht. Mit der Laravel-Autorisierung sammeln Sie genau solche Regeln an einem einzigen Ort, ohne Ihre Geschäftslogik zu verunreinigen. In diesem Leitfaden gehen wir durch, wann Sie eine Policy und wann eine Gate verwenden, wie Sie eine modellbasierte Zugriffskontrolle aufbauen und wie Sie diese in Ihren Controllern, in Blade und in der API-Schicht anwenden.

Authentifizierung und Autorisierung sind nicht dasselbe

Trennen wir zunächst die beiden Begriffe. Die Authentifizierung beantwortet die Frage „Wer bist du?“; darum kümmern sich der Login-Bildschirm, das Passwort und die Session. Die Autorisierung beantwortet die Frage „Darfst du das tun?“. Ein Benutzer kann angemeldet sein und trotzdem kein Recht haben, die Rechnung eines anderen Benutzers einzusehen. Laravel bietet zwei Hauptwerkzeuge für die Autorisierung: die Gate und die Policy.

Wann eine Gate, wann eine Policy

Beide nutzen dieselbe Engine, aber ihre Einsatzfälle unterscheiden sich:

  • Gate — ideal für einfache, weitreichende Berechtigungen, die nicht an ein bestimmtes Modell gebunden sind. Zum Beispiel „Zugriff auf das Admin-Panel“ oder „Website-Einstellungen ändern“. Gates basieren auf Closures und werden üblicherweise in AppServiceProvider definiert.
  • Policy — bündelt die Berechtigungen rund um ein einzelnes Eloquent-Modell (ansehen, erstellen, aktualisieren, löschen) in einer Klasse. Sie ist die richtige Wahl für die CRUD-Autorisierung von Modellen wie Post, Invoice oder Project.

Praktische Regel: Ist die Berechtigung an eine Modellzeile gebunden, verwenden Sie eine Policy; andernfalls eine Gate.

Eine einfache Berechtigung mit einer Gate definieren

Eine Regel, die nicht an ein Modell gebunden ist, können Sie direkt als Gate definieren. Der erste Parameter der Closure ist stets der authentifizierte Benutzer:

use Illuminate\Support\Facades\Gate;
use App\Models\User;

public function boot(): void
{
    Gate::define('access-admin', function (User $user) {
        return $user->is_admin;
    });
}

Zur Prüfung verwenden Sie Gate::allows() oder Gate::denies():

if (Gate::allows('access-admin')) {
    // Panel-Inhalt anzeigen
}

Eine Policy für modellbasierte Zugriffskontrolle erstellen

Die eigentliche Stärke liegt in den Policies. Eine für ein Modell zu generieren ist ein einziger Befehl:

php artisan make:policy PostPolicy --model=Post

Das Flag --model erzeugt das Gerüst der Standardmethoden wie view, create, update und delete. Anschließend füllen Sie sie gemäß Ihren Geschäftsregeln aus:

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
}

Ab Laravel 11 werden Policies automatisch erkannt, solange Sie der Namenskonvention folgen (App\Models\PostApp\Policies\PostPolicy); eine zusätzliche Registrierung ist nicht nötig. Benötigen Sie eine andere Zuordnung, können Sie sie mit Gate::policy(Post::class, PostPolicy::class) manuell binden.

Eine Policy in einem Controller verwenden

Innerhalb eines Controllers ist die sauberste Variante die Methode authorize. Ist die Regel nicht erfüllt, wirft Laravel automatisch eine 403-Antwort:

public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);

    $post->update($request->validated());

    return redirect()->route('posts.show', $post);
}

Möchten Sie alle CRUD-Methoden in einer Zeile zuordnen, verwenden Sie authorizeResource im Konstruktor des Controllers; es bindet die Methoden des Resource-Controllers automatisch an die Policy-Methoden:

public function __construct()
{
    $this->authorizeResource(Post::class, 'post');
}

Anwendung in Blade und der API-Schicht

Autorisierung darf nicht nur im Controller bleiben. Um in Blade eine Schaltfläche vor einem Benutzer ohne Berechtigung zu verbergen, verwenden Sie die Direktive @can:

@can('update', $post)
    <a href="{{ route('posts.edit', $post) }}">Bearbeiten</a>
@endcan

Um Routen für API- und Formularanfragen gesammelt zu schützen, erledigt die can-Middleware die Arbeit:

Route::put('/posts/{post}', [PostController::class, 'update'])
    ->middleware('can:update,post');

Sie können auch über ein Benutzerobjekt prüfen: $user->can('update', $post). Das ist praktisch, um in einer JSON-Antwort ein „darf bearbeiten?“-Flag an das Frontend zu senden.

Der before-Hook und häufige Fehler

Wenn Administratoren alles tun können sollen, fügen Sie der Policy eine before-Methode hinzu. Sie läuft vor allen anderen Prüfungen und überspringt den Rest, wenn sie true zurückgibt:

public function before(User $user, string $ability): ?bool
{
    return $user->is_admin ? true : null;
}

Hier null zurückzugeben ist entscheidend: Geben Sie false zurück, laufen die anderen Methoden nie und Sie sperren jeden aus, der kein Administrator ist. Weitere häufige Fehler: zu vergessen, den Parameter für Gäste (nicht authentifiziert) als ?User $user nullable zu machen, und authorize mit can zu verwechseln — Ersteres wirft eine Exception, Letzteres gibt einen boolean zurück.

Häufige Fragen

Sollte ich eine Policy oder eine Gate verwenden?

Ist die Berechtigung an eine Zeile eines bestimmten Eloquent-Modells gebunden (zum Beispiel „diesen Beitrag bearbeiten“), verwenden Sie eine Policy. Für allgemeine Berechtigungen, die nicht an ein Modell gebunden sind (zum Beispiel „auf das Panel zugreifen“), bleibt eine Gate einfacher.

Muss ich Policies manuell registrieren?

Für Laravel 11+ nein; sie werden automatisch erkannt, solange Sie der Namenskonvention folgen. Gate::policy() brauchen Sie nur für eine abweichende Modell-Policy-Zuordnung.

Kann ich statt eines schlichten 403 eine eigene Nachricht zurückgeben?

Ja. Indem Sie aus einer Policy-Methode Illuminate\Auth\Access\Response::deny('Nachricht') zurückgeben, können Sie eigenen Fehlertext und einen Statuscode liefern und statt true Response::allow() verwenden.

Die Autorisierung von Anfang an richtig aufzusetzen, hält Ihr Projekt sicher, während es wächst. Um eine saubere, wartbare Zugriffskontrolle in Ihrem Laravel-Projekt einzurichten, nehmen Sie Kontakt mit mir auf.

Bu kategorideki tüm yazılar →

Devamı için