Benutzerautorisierung


Benutzerautorisierung

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 AppProvidersAuthServiceProviderGate 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@methodStil:

/**
 * 注册任意用户认证、用户授权服务。
 *
 * @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 in

zugeordneten Richtlinien haben Vorrang vor automatisch erkannten Richtlinien. AuthServiceProvider

Schreibstrategie

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 Aktionsmethoden view, create, update und delete .

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 Option make: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
Dieser Artikel wurde zuerst auf der Website LearnKu.com veröffentlicht.