13.x der offiziellen Laravel-Dokumentation sowie auf die offizielle Implementierung und die Tests des neuesten Framework-Releases v13.42.0, geprüft am 10. November 2026. Die Grundlagen der Autorisierung finden Sie im Autorisierungs-Leitfaden, das Laden von Providern unter Paket-Auto-Discovery.
Nicht von der User-Klasse der nutzenden Anwendung abhängen
Als Beispiel fügen wir dem ModellAcme\Reports\Models\Report des Pakets eine Autorisierung für update hinzu. Vorausgesetzt wird, dass die Tabelle acme_reports eine Spalte owner_id hat, in der der Authentifizierungs-Identifier des Eigentümers gespeichert ist. Wie Sie Migrationen ausliefern, behandelt Paket-Migrationen.
src/Models/Report.php ist ein gewöhnliches Eloquent-Modell.
App\Models\User als Typ angibt, hängt sie vom Namespace und Modellaufbau der nutzenden Anwendung ab. Wenn Sie nur den Authentifizierungs-Identifier des Benutzers benötigen, verwenden Sie den Laravel-Vertrag Authenticatable.
Legen Sie Folgendes in src/Policies/ReportPolicy.php ab.
null-Identifier ausgeschlossen. Den Typunterschied zwischen einer Ganzzahl aus der Datenbank und einem String gleicht der Vergleich über Strings aus. In diesem Beispiel darf nur der Eigentümer aktualisieren. In Anwendungen mit mehreren Benutzertypen oder Guards prüfen Sie außerdem, ob der Identifier allein das Subjekt eindeutig bestimmt. Falls nicht, ersetzen Sie die Policy durch eine eigene, die Benutzertyp- oder Mandantengrenzen berücksichtigt.
Authenticatable ist ein Vertrag für Dinge wie den Authentifizierungs-Identifier. Er stellt weder isAdministrator() noch Methoden zum Abrufen von Rollen bereit. Wenn Sie paketeigene Berechtigungsinformationen benötigen, definieren Sie einen separaten Vertrag und lassen die nutzende Anwendung eine Implementierung injizieren.Die Zuordnung im Service-Provider registrieren
Registrieren Sie inboot() von src/ReportsServiceProvider.php nur die Modelle, die dem Paket gehören.
Gate::policy() speichert den Klassennamen der Policy unter dem Klassennamen des Modells. Die Registrierung selbst erzeugt keine Policy, führt keine Datenbankabfrage aus und prüft keinen Benutzer. Erst wenn die Policy benötigt wird, etwa durch Gate::getPolicyFor(), wird sie über make() des Containers erzeugt. Deshalb können Sie Abhängigkeiten in den Konstruktor der Policy injizieren.
Die Ablage von Report und ReportPolicy passt auch zur Standard-Auto-Discovery. Hier wird aber explizit registriert, um deutlich zu machen, welche Zuordnung das Paket bereitstellt. Die Registrierung allein wendet keine Autorisierung auf HTTP-Endpunkte an. Rufen Sie vor der Aktualisierung zum Beispiel im Controller Folgendes auf.
AuthorizationException ausgelöst, die in der normalen HTTP-Verarbeitung zu einer 403-Antwort wird. Die Argumente der Policy-Methode unterscheiden sich zwischen update, das ein Modell erhält, und Fähigkeiten wie create, die den Klassennamen des Modells erhalten. Richten Sie sich nach den Aufrufkonventionen im Autorisierungs-Leitfaden.
Die Auflösungsreihenfolge der Policies lesen
Gate::getPolicyFor() wandelt ein Objekt in seinen Klassennamen um und sucht in der folgenden Reihenfolge. Das ist die Reihenfolge der Policy-Auswahl, nicht die Ausführungsreihenfolge aller Autorisierungs-Hooks.
Solange es also eine explizite Registrierung für dieselbe Klasse
Report gibt, wird die Policy nicht ersetzt, wenn Sie nur #[UsePolicy] oder die Namenskonvention ändern. Verwendet die nutzende Anwendung dagegen ein Modell, das von Report erbt, haben Policies, die über das eigene Attribut der Kindklasse oder die Ableitung gefunden werden, Vorrang vor der expliziten Registrierung der Elternklasse. Prüfen Sie das auch mit der Modellklasse, die tatsächlich verwendet wird.
In der nutzenden Anwendung explizit überschreiben
Wenn Siepolicy() für dasselbe Modell erneut aufrufen, ersetzt die spätere Registrierung die Zuordnung. Sie einfach in das boot() eines anderen Providers zu legen, hängt von der Ladereihenfolge ab. Eine Möglichkeit ist, in AppServiceProvider::boot() der nutzenden Anwendung einen Callback für den Abschluss des Bootvorgangs zu registrieren.
ApplicationReportPolicy ist eine Policy, die die nutzende Anwendung implementiert. Registriert das Paket in einem normalen boot(), läuft dieser Callback danach. Es ist kein Mechanismus, der bedingungslos Vorrang hat, auch nicht gegenüber erneuten Registrierungen in anderen Booted-Callbacks oder später geladenen Providern. Der registrierende Provider des Paketes ist in diesem Beispiel kein Deferred Provider.
Alternativ können Sie die Zuordnung unverändert lassen und im Container das Auflösungsziel von ReportPolicy::class ersetzen. resolvePolicy() lässt die Policy jedes Mal vom Container auflösen, ob dabei tatsächlich eine neue Instanz entsteht, hängt aber vom Binding dieser Policy ab. Vermeiden Sie Designs, die Benutzer- oder Request-Informationen im Konstruktor holen und in einer Singleton-Policy festhalten.
Hooks mit Auswirkung auf die gesamte Autorisierung trennen
Bei einer normalen Gate-Prüfung läuft zuerst das globaleGate::before(). Gibt es einen anderen Wert als null zurück, wird die Entscheidung der Policy nicht ausgeführt.
Das Diagramm zeigt nur den Pfad, auf dem eine Policy gefunden wird und die passende Methode aufgerufen werden kann. Die anschließenden globalen after-Hooks und den Rückfall auf Gate-Definitionen, wenn der Policy die Zielmethode fehlt, lässt es aus.
Registrieren Sie kein globales Gate::before(), das alle Fähigkeiten erlaubt, nur um eine Administrator-Behandlung im Paket umzusetzen. Damit würden Sie auch die Autorisierung anderer Pakete und der nutzenden Anwendung freigeben. Ein before() innerhalb der Policy gilt nur für diese Policy, wird aber nicht aufgerufen, wenn es keine Methode für die Fähigkeit gibt. Wenn die folgende Methode entscheiden soll, geben Sie null statt false zurück.
Außerdem verlangt update() in diesem Beispiel ein nicht-nullable Authenticatable, sodass die Policy-Methode für Gäste nicht ausgeführt wird. Ohne Überschreiben des Ergebnisses, etwa durch globale Hooks, wird die Anfrage abgelehnt. Wenn Sie Gäste zulassen wollen, etwa für öffentliches Lesen, sehen Sie separat ein nullable Benutzerargument und eine explizite Prüfung vor.
Registrierung und Entscheidung getrennt testen
Vorausgesetzt wird die in Paket-Tests vorgestellte Testbench-Basisklasse, dieReportsServiceProvider::class in getPackageProviders() lädt. Das folgende Beispiel ist tests/Feature/ReportPolicyTest.php. Als Benutzer dient das generische Authentifizierungsmodell von Laravel, sodass Sie ohne Speichern in der Datenbank prüfen können.
forUser() schreibt den Benutzer des gemeinsamen Gates nicht um. Es erzeugt ein separates Gate und übergibt ihm die Zuordnungen, Fähigkeiten und Callbacks zum jeweiligen Zeitpunkt. Ein bereits erzeugtes benutzerspezifisches Gate sieht daher spätere Änderungen an Policy-Registrierungen des gemeinsamen Gates nicht. Schließen Sie die Registrierung beim Booten ab und speichern Sie benutzerspezifische Gates nicht in langlebigen Services.
In der nutzenden Anwendung brauchen Sie außerdem Prüfungen mit dem echten Guard und Benutzermodell sowie HTTP-Tests für den Update-Endpunkt. Die obigen Tests allein prüfen weder, ob die Route autorisiert ist, noch das Speicherformat des Eigentümer-Identifiers in der Datenbank.
Bei Updates einzuhaltende Verträge
- Sind die Ergebnisse für Eigentümer, Nicht-Eigentümer, Gäste und Datensätze ohne Eigentümer unverändert?
- Stimmen die veröffentlichten Fähigkeitsnamen mit den Argumenten der Policy-Methoden überein?
- Funktioniert das Ersetzen der Policy durch die nutzende Anwendung weiterhin?
- Wird bei unterstützten Kindmodellen für die Kindklasse tatsächlich die richtige Policy gewählt?
- Werden echte Update-Requests einschließlich der globalen Hooks der Anwendung wie erwartet erlaubt oder abgelehnt?
Primärquellen
- Offizielle Laravel-Dokumentation: Autorisierung
- Offizielle Laravel-Dokumentation: Paketentwicklung
- Framework v13.42.0: Registrierung, Auflösung und forUser des Gates
- Framework v13.42.0: AuthServiceProvider, der das Gate als Singleton registriert
- Framework v13.42.0: boot und booted der Application
- Framework v13.42.0: Offizielle Tests des Autorisierungs-Gates