Tutoriel Vidéo Laravel Gates et Policies

Télécharger la vidéo

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