Heim >Backend-Entwicklung >PHP-Tutorial >Tore und Strategien in Laravel

Tore und Strategien in Laravel

WBOY
WBOYOriginal
2023-08-31 13:49:061544Durchsuche

Tore und Strategien in Laravel

Heute werden wir das Autorisierungssystem des Laravel-Webframeworks besprechen. Das Laravel-Framework implementiert Autorisierung in Form von Gates und Richtlinien. Nachdem ich Gates und Strategien vorgestellt habe, demonstriere ich die Konzepte durch die Implementierung eines benutzerdefinierten Beispiels.

Ich gehe davon aus, dass Sie bereits über das integrierte Laravel-Authentifizierungssystem Bescheid wissen, da dieses zum Verständnis des Autorisierungskonzepts erforderlich ist. Offensichtlich arbeitet das Autorisierungssystem mit dem Authentifizierungssystem zusammen, um legitime Benutzersitzungen zu identifizieren.

Wenn Sie sich mit dem Laravel-Authentifizierungssystem nicht auskennen, empfehle ich Ihnen dringend, die offizielle Dokumentation zu lesen, sie wird Ihnen ein tiefgreifendes Verständnis des Themas vermitteln.

Laravel-Autorisierungsmethode

Inzwischen sollten Sie wissen, dass es das Laravel-Autorisierungssystem in zwei Formen gibt: Gates und Richtlinien. Auch wenn sich das wie eine komplizierte Sache anhört, würde ich sagen, dass es ziemlich einfach ist, wenn man erst einmal den Dreh raus hat!

Gate ermöglicht Ihnen die Definition von Autorisierungsregeln mithilfe eines einfachen, auf Schließungen basierenden Ansatzes. Mit anderen Worten: Wenn Sie Vorgänge autorisieren möchten, die nicht an ein bestimmtes Modell gebunden sind, sind Gates der perfekte Ort, um diese Logik zu implementieren.

Werfen wir einen kurzen Blick darauf, wie eine Gate-basierte Autorisierung aussieht:

...
...
Gate::define('update-post', function ($user, $post) {
  return $user->id == $post->user_id;
});
...
...

Das obige Code-Snippet definiert die Autorisierungsregeln update-post Sie können es von überall in Ihrer Anwendung aufrufen.

Wenn Sie andererseits die Autorisierungslogik für ein beliebiges Modell gruppieren möchten, sollten Sie Strategien verwenden. Angenommen, Sie haben ein Post-Modell in Ihrer Anwendung und möchten CRUD-Vorgänge für dieses Modell autorisieren. In diesem Fall ist dies die Strategie, die Sie umsetzen müssen.

class PostPolicy
{
  public function view(User $user, Post $post) {}
  public function create(User $user) {}
  public function update(User $user, Post $post) {}
  public function delete(User $user, Post $post) {}
}

Wie Sie sehen können, handelt es sich hierbei um eine sehr einfache Richtlinienklasse, die die Autorisierung für Post die CRUD-Operationen des Modells definiert.

Das ist es, eine Einführung in Tore und Strategien in Laravel. Ab dem nächsten Abschnitt werden wir jedes Element praktisch demonstrieren.

Tür

In diesem Abschnitt werden wir das Konzept von Türen anhand eines Beispiels aus der Praxis verstehen.

So erstellen Sie eine individuelle Tür

Wenn Sie eine Komponente oder einen Dienst registrieren müssen, suchen Sie normalerweise nach einem Laravel-Dienstleister. Lassen Sie uns gemäß dieser Konvention fortfahren und das benutzerdefinierte Gate in app/Providers/AuthServiceProvider.php definieren, wie im folgenden Codeausschnitt gezeigt.

<?php
namespace App\Providers;
 
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
 
class AuthServiceProvider extends ServiceProvider
{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
  ];
 
  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
    $this->registerPolicies();
     
    Gate::define('update-post', function ($user, $post) {
      return $user->id == $post->user_id;
    });
  }
}

In der boot-Methode definieren wir die benutzerdefinierte Tür:

Gate::define('update-post', function ($user, $post) {
  return $user->id == $post->user_id;
});

Wenn Sie ein Gate definieren, erfordert es einen Abschluss, der TRUEFALSE basierend auf der in der Gate-Definition definierten Autorisierungslogik zurückgibt. Neben Abschlussfunktionen gibt es noch andere Möglichkeiten, Gates zu definieren.

Zum Beispiel ruft die folgende Gate-Definition eine Controller-Aktion anstelle einer Abschlussfunktion auf.

Gate::define('update-post', 'ControllerName@MethodName');

So verwenden Sie unsere maßgeschneiderten Tore

Lassen Sie uns nun fortfahren und eine benutzerdefinierte Route hinzufügen, damit wir demonstrieren können, wie die Gate-basierte Autorisierung funktioniert. Fügen Sie in der Routendatei routes/web.php die folgenden Routen hinzu.

Route::get('service/post/gate', 'PostController@gate');

Lassen Sie uns auch eine zugehörige Controller-Datei erstellen app/Http/Controllers/PostController.php.

<?php
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Post;
use Illuminate\Support\Facades\Gate;
 
class PostController extends Controller
{
  /* Make sure you don't use Gate and Policy altogether for the same Model/Resource */
  public function gate()
  {
    $post = Post::find(1);
 
    if (Gate::allows('update-post', $post)) {
      echo 'Allowed';
    } else {
      echo 'Not Allowed';
    }
     
    exit;
  }
}

In den meisten Fällen werden Sie am Ende die Methode erlaubt oder verweigert verwenden (Gate Aussehen), um bestimmte Vorgänge zu autorisieren. Im obigen Beispiel verwenden wir die Methode <code class="inline">allows, um zu prüfen, ob der aktuelle Benutzer die Aktion allowsdenies 方法(Gate 外观)来授权特定操作。在上面的示例中,我们使用 allows 方法来检查当前用户是否能够执行 update-post ausführen kann.

Scharfäugige Benutzer werden bemerken, dass wir nur den zweiten Parameter $post 传递给了闭包。第一个参数是当前登录的用户,由 GateFassade automatisch einfügen.

So sollten Sie Gates verwenden, um Aktionen in Ihrer Laravel-Anwendung zu autorisieren. Wenn Sie die Autorisierung für Ihr Modell implementieren möchten, wird im nächsten Abschnitt erläutert, wie Sie Richtlinien verwenden.

Richtlinie

Wie wir bereits besprochen haben, benötigen Sie eine Richtlinie, wenn Sie Autorisierungsvorgänge für ein bestimmtes Modell oder eine bestimmte Ressource logisch gruppieren möchten.

So erstellen Sie eine individuelle Strategie

In diesem Abschnitt erstellen wir eine Richtlinie für das Post 模型创建一个策略,用于授权所有 CRUD 操作。我假设您已经在应用程序中实现了 Post-Modell, die alle CRUD-Vorgänge autorisiert. Ich gehe davon aus, dass Sie das

-Modell bereits in Ihrer Anwendung implementiert haben. Andernfalls reicht etwas Ähnliches aus.

artisan 命令是创建存根代码时最好的朋友。您可以使用以下 artisan 命令为 PostDer Laravel-Befehl artisan ist Ihr bester Freund beim Erstellen von Stub-Code. Sie können den folgenden artisan-Befehl verwenden, um eine Strategie für das

-Modell zu erstellen.

$php artisan make:policy PostPolicy --model=Post
--model=PostWie Sie sehen können, stellen wir den Parameter bereit, damit alle CRUD-Methoden erstellt werden. Wenn nicht, wird eine leere Richtlinienklasse erstellt. Sie finden die neu erstellte Richtlinienklasse in app/Policies/PostPolicy.php

.

<?php

namespace App\Policies;

use App\Post;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class PostPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view any models.
     *
     * @param  \App\User  $user
     * @return mixed
     */
    public function viewAny(User $user)
    {
        //
    }

    /**
     * Determine whether the user can view the model.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function view(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can create models.
     *
     * @param  \App\User  $user
     * @return mixed
     */
    public function create(User $user)
    {
        //
    }

    /**
     * Determine whether the user can update the model.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function update(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can delete the model.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function delete(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can restore the model.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function restore(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can permanently delete the model.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function forceDelete(User $user, Post $post)
    {
        //
    }
}

Ersetzen wir es durch den folgenden Code.

<?php
namespace App\Policies;
 
use App\User;
use App\Post;
use Illuminate\Auth\Access\HandlesAuthorization;
 
class PostPolicy
{
  use HandlesAuthorization;
 
  /**
   * Determine whether the user can view the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function view(User $user, Post $post)
  {
    return TRUE;
  }
 
  /**
   * Determine whether the user can create posts.
   *
   * @param  \App\User  $user
   * @return mixed
   */
  public function create(User $user)
  {
    return $user->id > 0;
  }
 
  /**
   * Determine whether the user can update the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function update(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }
 
  /**
   * Determine whether the user can delete the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function delete(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }
}

Um unsere Strategieklasse nutzen zu können, müssen wir sie beim Laravel-Dienstanbieter registrieren, wie im folgenden Codeausschnitt gezeigt.

<?php
namespace App\Providers;
 
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use App\Post;
use App\Policies\PostPolicy;
 
class AuthServiceProvider extends ServiceProvider
{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
    Post::class => PostPolicy::class
  ];
 
  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
    $this->registerPolicies();
  }
}
$policiesWir haben die Richtlinienzuordnung im Attribut

hinzugefügt. Es weist Laravel an, die entsprechende Richtlinienmethode aufzurufen, um CRUD-Operationen zu autorisieren. 🎜

您还需要使用 registerPolicies 方法注册策略,就像我们在 boot 方法中所做的那样。

没有模型的策略方法

PostPolicy 策略类中的 create 方法仅采用单个参数,这与采用两个参数的其他模型方法不同。一般来说,第二个参数是模型对象,您将在执行授权时使用它。但是,在 create 方法的情况下,您只需要检查是否允许相关用户创建新帖子。

在下一节中,我们将了解如何使用自定义策略类。

如何使用我们的自定义策略类

更进一步,让我们在 routes/web.php 文件中创建几个自定义路由,以便我们可以在那里测试我们的策略方法。

Route::get('service/post/view', 'PostController@view');
Route::get('service/post/create', 'PostController@create');
Route::get('service/post/update', 'PostController@update');
Route::get('service/post/delete', 'PostController@delete');

最后,让我们在 app/Http/Controllers/PostController.php 创建一个关联的控制器。

<?php
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Post;
use Illuminate\Support\Facades\Auth;
 
class PostController extends Controller
{
  public function view()
  {
    // get current logged in user
    $user = Auth::user();
     
    // load post
    $post = Post::find(1);
     
    if ($user->can('view', $post)) {
      echo "Current logged in user is allowed to update the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }
 
  public function create()
  {
    // get current logged in user
    $user = Auth::user();
 
    if ($user->can('create', Post::class)) {
      echo 'Current logged in user is allowed to create new posts.';
    } else {
      echo 'Not Authorized';
    }
 
    exit;
  }
 
  public function update()
  {
    // get current logged in user
    $user = Auth::user();
 
    // load post
    $post = Post::find(1);
 
    if ($user->can('update', $post)) {
      echo "Current logged in user is allowed to update the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }
 
  public function delete()
  {
    // get current logged in user
    $user = Auth::user();
     
    // load post
    $post = Post::find(1);
     
    if ($user->can('delete', $post)) {
      echo "Current logged in user is allowed to delete the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }
}

您可以通过不同的方式使用策略来授权您的操作。在上面的示例中,我们使用 User 模型来授权我们的 Post 模型操作。

User 模型提供了两种有用的授权方法 — cancantcan 方法用于检查当前用户是否能够执行某个操作。而与 can 方法对应的 cant 方法,用于判断动作是否无法执行。

让我们从控制器中获取 view 方法的片段,看看它到底做了什么。

public function view()
{
  // get current logged in user
  $user = Auth::user();
   
  // load post
  $post = Post::find(1);
   
  if ($user->can('view', $post)) {
    echo "Current logged in user is allowed to update the Post: {$post->id}";
  } else {
    echo 'Not Authorized.';
  }
}

首先,我们加载当前登录的用户,这为我们提供了 User 模型的对象。接下来,我们使用 Post 模型加载示例帖子。

接下来,我们使用 User 模型的 can 方法来授权 Post 模型的 view 操作。 can 方法的第一个参数是您要授权的操作名称,第二个参数是您要授权的模型对象。

这是如何使用 User 模型通过策略授权操作的演示。或者,如果您在控制器中授权某个操作,则也可以使用控制器助手。

…
$this->authorize('view', $post);
…

如您所见,如果您使用控制器助手,则无需加载 User 模型。

如何通过中间件使用策略

或者,Laravel 还允许您使用中间件授权操作。让我们快速查看以下代码片段,了解如何使用中间件来授权模型操作。

Route::put('/post/{post}', function (Post $post) {
    // Currently logged-in user is allowed to update this post.... 
})->middleware('can:update,post');

在上面的示例中,它将使用 can 中间件。我们传递两个参数:第一个参数是我们想要授权的操作,第二个参数是路由参数。根据隐式模型绑定的规则,第二个参数会自动转换为 Post 模型对象,并作为第二个参数传递。如果当前登录的用户无权执行 update 操作,Laravel 将返回 403 状态代码错误。

如何将策略与刀片模板结合使用

如果您希望在登录用户被授权执行特定操作时显示代码片段,您还可以在刀片模板中使用策略。让我们快速看看它是如何工作的。

@can('delete', $post)
    <!-- Display delete link here... -->
@endcan

在上述情况下,它只会向有权对 Post 模型执行删除操作的用户显示删除链接。

这就是您可以使用的策略概念,在授权模型或资源时它非常方便,因为它允许您将授权逻辑分组在一个地方。

只需确保您不会将门和策略一起用于模型的相同操作,否则会产生问题。这就是我今天的内容,今天就到此为止!

结论

今天,Laravel 授权占据了我文章的中心位置。在文章的开头,我介绍了 Laravel 授权、网关和策略的主要要素。

接下来,我们创建了自定义门和策略,以了解它在现实世界中的工作原理。我希望您喜欢这篇文章,并在 Laravel 环境中学到了一些有用的东西。

对于刚刚开始使用 Laravel 或希望通过扩展来扩展您的知识、网站或应用程序的人,我们在 Envato Market 上提供了多种可供您学习的内容。

Das obige ist der detaillierte Inhalt vonTore und Strategien in Laravel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn