Aujourd'hui, nous allons discuter du système d'autorisation du framework Web Laravel. Le framework Laravel implémente l'autorisation sous la forme de portes et de politiques. Après avoir présenté les portes et les stratégies, je démontrerai les concepts en implémentant un exemple personnalisé.
Je suppose que vous connaissez déjà le système d'authentification Laravel intégré, car cela est nécessaire pour comprendre le concept d'autorisation. Évidemment, le système d'autorisation fonctionne en collaboration avec le système d'authentification pour identifier les sessions utilisateur légitimes.
Si vous ne connaissez pas le système d'authentification Laravel, je vous recommande fortement de lire la documentation officielle, elle vous donnera une compréhension approfondie du sujet.
À présent, vous devez savoir que le système d'autorisation Laravel se présente sous deux formes : les portes et les politiques. Même si cela peut paraître compliqué, je dirais qu’une fois qu’on a compris, c’est assez facile à faire !
Gate vous permet de définir des règles d'autorisation en utilisant une approche simple basée sur la fermeture. En d’autres termes, lorsque vous souhaitez autoriser des opérations qui ne sont liées à aucun modèle particulier, les portes sont l’endroit idéal pour mettre en œuvre cette logique.
Jetons un coup d'œil rapide à ce à quoi ressemble l'autorisation basée sur une porte :
... ... Gate::define('update-post', function ($user, $post) { return $user->id == $post->user_id; }); ... ...
L'extrait de code ci-dessus définit les règles d'autorisation update-post
Vous pouvez l'appeler depuis n'importe où dans votre application.
D'un autre côté, lorsque vous souhaitez regrouper la logique d'autorisation pour n'importe quel modèle, vous devez utiliser des stratégies. Par exemple, disons que vous avez un modèle Post
dans votre application et que vous souhaitez autoriser les opérations CRUD sur ce modèle. Dans ce cas, c’est la stratégie que vous devez mettre en œuvre.
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) {} }
Comme vous pouvez le voir, il s'agit d'une classe de politique très simple qui définit l'autorisation pour Post
les opérations CRUD du modèle.
Ça y est, une introduction aux portes et aux stratégies dans Laravel. À partir de la section suivante, nous donnerons une démonstration pratique de chaque élément.
Dans cette section, nous comprendrons le concept de portes à travers un exemple concret.
Lorsque vous devez enregistrer un composant ou un service, vous recherchez généralement un fournisseur de services Laravel. Suite à cette convention, allons de l'avant et définissons la porte personnalisée dans app/Providers/AuthServiceProvider.php comme indiqué dans l'extrait de code suivant.
<?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; }); } }
Dans la méthode boot
, nous définissons la porte personnalisée :
Gate::define('update-post', function ($user, $post) { return $user->id == $post->user_id; });
Lorsque vous définissez une porte, elle nécessite une fermeture qui renvoie TRUE
或 FALSE
en fonction de la logique d'autorisation définie dans la définition de la porte. Il existe d'autres façons de définir des portes en plus des fonctions de fermeture.
Par exemple, la définition de porte suivante appelle une action de contrôleur au lieu d'une fonction de fermeture.
Gate::define('update-post', 'ControllerName@MethodName');
Maintenant, allons de l'avant et ajoutons un itinéraire personnalisé afin que nous puissions démontrer le fonctionnement de l'autorisation basée sur la porte. Dans le fichier de routes routes/web.php, ajoutez les routes suivantes.
Route::get('service/post/gate', 'PostController@gate');
Créons également un fichier de contrôleur associé 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; } }
Dans la plupart des cas, vous finirez par utiliser la méthode allows
ou denies
(Gate< / code>apparence) pour autoriser des opérations spécifiques. Dans l'exemple ci-dessus, nous utilisons la méthode <code class="inline">allows
pour vérifier si l'utilisateur actuel est capable d'effectuer l'action allows
或 denies
方法(Gate
外观)来授权特定操作。在上面的示例中,我们使用 allows
方法来检查当前用户是否能够执行 update-post
.
Les utilisateurs aux yeux d'aigle remarqueront que nous injectons automatiquement uniquement le deuxième paramètre $post
传递给了闭包。第一个参数是当前登录的用户,由 Gate
façade.
C'est ainsi que vous devez utiliser les portes pour autoriser des actions dans votre application Laravel. Si vous souhaitez implémenter l'autorisation pour votre modèle, la section suivante explique comment utiliser les stratégies.
Comme nous l'avons vu précédemment, lorsque vous souhaitez regrouper logiquement les opérations d'autorisation pour un modèle ou une ressource spécifique, vous avez besoin d'une politique.
Dans cette section, nous allons créer une politique pour le modèle Post
模型创建一个策略,用于授权所有 CRUD 操作。我假设您已经在应用程序中实现了 Post
qui autorisera toutes les opérations CRUD. Je suppose que vous avez déjà implémenté le modèle
artisan
命令是创建存根代码时最好的朋友。您可以使用以下 artisan
命令为 Post
La commande Laravel artisan
est votre meilleure amie lors de la création de code stub. Vous pouvez utiliser la commande artisan
suivante pour créer une stratégie pour le modèle
$php artisan make:policy PostPolicy --model=Post
--model=Post
Comme vous pouvez le voir, nous fournissons le paramètre pour qu'il crée toutes les méthodes CRUD. Sinon, cela crée une classe de stratégie vide. Vous pouvez trouver la classe de stratégie nouvellement créée dans 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) { // } }
<?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; } }
<?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(); } }
$policies
Nous avons ajouté le mappage des politiques dans l'attribut . Il indique à Laravel d'appeler la méthode de politique appropriée pour autoriser les opérations CRUD. 🎜
您还需要使用 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
模型提供了两种有用的授权方法 — can
和 cant
。 can
方法用于检查当前用户是否能够执行某个操作。而与 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 上提供了多种可供您学习的内容。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!