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