Le contenu de cet article concerne l'implémentation des fonctions d'autorisation utilisateur et de vérification des autorisations ACL dans le framework Laravel 5.1. Il a une certaine valeur de référence et j'espère qu'il pourra aider les amis dans le besoin.
1. Introduction
La fonction d'authentification prête à l'emploi fournie par Laravel rend l'enregistrement, la connexion, la déconnexion et la réinitialisation du mot de passe des utilisateurs pratiques et simples.
Mais si vous devez contrôler l'accès à des parties spécifiques du site, ou autoriser des non-administrateurs à ouvrir/fermer des pages spécifiques, ou garantir que certains utilisateurs ne peuvent modifier que les éléments qu'ils publient (comme des articles), alors vous devez introduire Utilisez un outil comme BeatSwitch Lock ou écrire manuellement une telle fonction vous-même. Nous appelons une telle fonctionnalité ACL : Access Control Lists, qui sont utilisées pour définir les autorisations d'un utilisateur pour utiliser ou afficher des éléments spécifiques en fonction de ses attributs d'enregistrement utilisateur.
Heureusement, à partir de Laravel 5.1.11, Laravel fournit des fonctions d'autorisation prêtes à l'emploi pour répondre aux exigences ci-dessus. Nous n'avons plus besoin de faire de travail supplémentaire, il suffit de l'utiliser.
Remarque : avant de commencer cette section, veuillez vous référer au guide de mise à niveau pour mettre à niveau Laravel vers Laravel 5.1.11, sinon les fonctions associées ne seront pas implémentées.
2. Que peut-on faire ?
L'ACL prête à l'emploi fournie par Laravel s'appelle Gate (ce n'est pas un nom de produit comme Spark, mais juste le nom d'une classe et d'une façade).
L'utilisation de la classe Gate (injection ou utilisation de la façade Gate) nous permet de vérifier facilement si un certain utilisateur (utilisateur actuellement connecté ou utilisateur spécifié) est autorisé à faire fonctionner des choses spécifiques. Le code de vérification est le suivant :
if (Gate::denies('update-post', $post)) { abort(403); }
Mettez ce code dans le contrôleur, il utilisera la règle update-post définie pour vérifier si l'utilisateur actuellement authentifié a la permission de mettre à jour l'article spécifié.
Vous pouvez également utiliser Gate::allows, qui est à l'opposé de la méthode denies, et peut également être utilisé via @can dans le modèle de vue Blade, et il y en a bien d'autres, jetons un coup d'œil ensuite.
3. Comment utiliser ?
Laravel ACL est construit sur le concept de "permissions". Les autorisations incluent une clé (telle que update-post) et une fermeture qui renvoie vrai ou faux (les paramètres peuvent être transmis).
3.1 Définir les autorisations
Définissons l'autorisation de publication de mise à jour de l'utilisateur update-post dans AuthServiceProvider comme suit :
<?php namespace App\Providers; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider{ /** * 注册应用所有的认证/授权服务. * * @param \Illuminate\Contracts\Auth\Access\Gate $gate * @return void */ public function boot(GateContract $gate) { parent::registerPolicies($gate); $gate->define('update-post', function ($user, $post) { return $user->id === $post->user_id; }); } }
Comme vous pouvez le voir Oui, le premier paramètre définissant la fermeture de l'autorisation est l'utilisateur spécifié. Si l'utilisateur actuel ne réussit pas l'authentification de connexion, Gate renverra automatiquement false.
Bien sûr, en plus des fermetures, vous pouvez également remplacer les fermetures par des méthodes de classe comme deuxième paramètre, qui seront analysées dans le conteneur :
$gate->define( 'update -post', 'PostPolicy@update');
3.2 Vérifier les autorisations via la façade Gate
Gate fournit les méthodes suivantes pour vérifier les autorisations : check, Les fonctions d'autorisation et de refus, de vérification et d'autorisation sont exactement les mêmes, tandis que les fonctions de refus et d'autorisation sont opposées.
Si vous utilisez le portail pour vérifier les autorisations, vous n'avez pas besoin de transmettre l'instance de l'utilisateur, la façade du portail transmettra automatiquement l'utilisateur actuel :
if (Gate::denies('update-post', $post)) { abort(403); }
Si vous définissez plusieurs paramètres dans les autorisations :
Gate::define('delete-comment', function ($user, $post, $comment) { // });
La méthode de vérification est la suivante :
if (Gate::allows('delete-comment', [$post, $comment])) { // }
Si vous souhaitez vérifier si un utilisateur non actuellement authentifié a l'autorisation d'opérer, la méthode d'appel est comme suit :
if (Gate::forUser($user)->allows('update-post', $post)) { // }
3.3 Utiliser l'injection Gate pour vérifier les autorisations
Comme toujours, vous pouvez injecter la classe Gate au lieu d'utiliser sa façade. le même que vous dans AuthServiceProvider - IlluminateContractsAuthAccessGate :
public function somethingResolvedFromContainer(Gate $gate) { if ($gate->denies('update-post')) { // etc. } }
3.4 Utiliser le modèle User pour vérifier les autorisations
Le modèle AppUser de Laravel utilise désormais le trait Authorizing, vous pouvez donc utilisez les méthodes can et can qu'il fournit, qui correspondent respectivement aux méthodes d'autorisation et de refus de la porte.
Nous pouvons donc également utiliser le modèle utilisateur pour vérifier les autorisations :
public function update(Request $request, $id) { $post = Post::findOrFail($id); if ($request->user()->cannot('update-post', $post)) { abort(403); } // 更新文章... }
3.5 Vérifier les autorisations dans Blade
Vous pouvez utiliser dans Blade The @ peut commander pour vérifier les autorisations :
<a href="/post/{{ $post->id }}">查看文章</a> @can('update-post', $post) <a href="/post/{{ $post->id }}/edit">编辑文章</a> @endcan
Le contraire est la commande @else :
@can('update-post', $post) <!-- The Current User Can Update The Post --> @else <!-- The Current User Can't Update The Post --> @endcan
3.6 Abandonner la vérification des autorisations
Et si l'administrateur ou le superutilisateur a toutes les autorisations ? Ou que se passe-t-il si vous souhaitez modifier temporairement la logique ACL pour les utilisateurs ?
La méthode before fournie par Gate permet de revenir avant d'effectuer d'autres vérifications dans certains cas précis, sans vérifier davantage les autorisations :
$gate->before(function ($user, $ability) { if ($user->last_name === 'Stauffer') { return true; } });
Ou en utilisant celles de l'utilisateur :
$gate->before(function ($user, $ability) { if ($user->isOwner()) { return true; } });
3.7 Classe de stratégie
À mesure que la logique des applications devient de plus en plus complexe, de plus en plus d'autorisations doivent être traitées. Définir toutes les autorisations dans AuthServiceProvider n'est évidemment pas la même chose. Il est sage de le faire, c'est pourquoi Laravel introduit des classes de stratégie. Les classes de stratégie sont des classes PHP natives. De la même manière que les contrôleurs regroupent les itinéraires en fonction des ressources, les classes de stratégie gèrent les autorisations en groupes en fonction des ressources.
Générer une classe de stratégie
Vous pouvez utiliser la commande Artisan suivante pour générer la classe de stratégie PostPolicy :
php artisan make:policy PostPolicy
La classe de stratégie générée se trouve dans le répertoire app/Policies.
Ensuite, nous pouvons enregistrer la classe de politique dans l'attribut politiques d'AuthServiceProvider :
protected $policies = [ Post::class => PostPolicy::class, ];
Ci-dessous, nous modifions la PostPolicy comme suit :
<?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; } }
Remarque : Toutes les politiques classes pass Le conteneur de services effectue la résolution, ce qui signifie que vous pouvez taper toutes les dépendances dans le constructeur de la classe de stratégie et elles seront automatiquement injectées.
Vérifier la stratégie
如果为某个资源类型定义了策略类,Gate将会使用第一个参数来判断检查策略类上的哪个方法。
因此,要检查是否有权限更新某篇文章,只需要传入文章实例和update权限:
<?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新给定文章 * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); if (Gate::denies('update', $post)) { abort(403); } // 更新文章... } }
当然也可以使用User模型和Blade指令检查权限。
此外,Laravel还提供了一个全局帮助函数policy来检查权限:
if (policy($post)->update($user, $post)) { // }
3.8 控制器授权
由于大多数授权都会在检查权限失败的情况下退出控制器方法,因此在控制器中检查权限有一条捷径(AuthorizesRequeststrait提供,该trait在基类控制器Controller中被使用):
<?php namespace App\Http\Controllers; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新给定文章 * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); $this->authorize('update', $post); // 更新文章... } }
和我们上面的例子一样,如果授权失败会抛出403错误。
最后,如果你的控制器方法名和策略类中的方法名相同,例如都是update,则可以省略authorize的第一个参数:
public function update($id){ $post = Post::findOrFail($id); $this->authorize($post); // 更新文章... }
此外,AuthorizesRequests也提供了对非当前认证用户权限检查的支持:
$this->authorizeForUser($user, 'update', $post);
相关文章推荐:
Laravel 5.1框架中如何创建自定义Artisan控制台命令
相关课程推荐:
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!