Gates et Policies

Résumé Support

En plus du système d'autorisation, Laravel offre aussi un système simple pour gérer les niveaux d'accès à une certaine resource. Par exemple un utilisateur peut modifier un article seulement si il en est l'auteur.

Pour gérer ce niveau d'accès Laravel propose 2 outils : les Gates et les Policies.

Gates

Les Gates permettent de définir simplement une permission gràce à l'utilisation d'une Closure qui devra retourner un booléen. Ces permissions seront définies dans la méthode boot() du App\Providers\AuthServiceProvider.

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

Une fois cette permission définie, il est possible de vérifier la permission depuis un controller à l'aide de la méthode allows ou denies.

if (Gate::allows('update-post', $post)) { // L'utilisateur en cours a le droit de mettre à jour l'article } if (Gate::denies('update-post', $post)) { // L'utilisateur en cours n'a le droit de mettre à jour l'article } // On peut aussi spécifier l'utilisateur sur lequel on doit vérifier la permission if (Gate::forUser($user)->allows('update-post', $post)) { // ... }

Policies

Les Policies permettent de regrouper les permissions qui concernent un modèle particulier. Pour générer une politique il est possible d'utiliser la commande artisan.

php artisan make:policy PostPolicy --model=Post

Cette commande va générer un fichier de politique prérempli des permissions view, update, create et delete.

<?php namespace App\Policies; use App\User; use App\Post; class PostPolicy { public function before(User $user, $ability) { if ($user->isAdmin()) { return true; } } public function update(User $user, Post $post) { return $user->id === $post->user_id; } // ... }

Il est d'ailleurs possible de créer une méthode before qui permet de court-circuiter les autres règles en renvoyant true ou false.

Une fois ce fichier de politique créé on peut l'associer à un modèle en utilisant le tableau policies dans l'AuthServiceProvider.

protected $policies = [ Post::class => PostPolicy::class, ];

Maintenant il est possible de vérifier si un utilisateur a le droit d'effectuer une certaine action.

if ($user->can('update', $post)) { // } // ou on renvoit une exception si l'utilisateur n'a pas la permission $this->authorize('update', $post); // et dans les vues @can('update', $post) ... @endcan