Aller au contenu
PROJET WEB DYNAMIQUE

Policies

Gestion des policies avec Laravel et Inertia.js

Laravel fournit un puissant système de policies pour gérer les autorisations d’accès aux fonctionnalités d’une application. Cependant, avec Inertia.js, les helpers Blade comme @can ou @cannot ne sont pas disponibles. La solution consiste à transmettre explicitement les permissions au frontend sous forme de props.

Comment fonctionnent les policies dans Laravel ?

Une policy dans Laravel définit les règles d’autorisation pour un modèle. Par exemple, pour un modèle Post, une policy pourrait définir si un utilisateur peut éditer ou supprimer un article :

public function edit(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

Avec Blade, on utiliserait cette policy ainsi :

@can('edit', $post)
    <a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcan

Avec Inertia.js, il faut transmettre ces autorisations au frontend via les props.

Transmettre les permissions au frontend

Dans le backend, les autorisations sont vérifiées avec les méthodes des policies et envoyées au composant Vue.js via les props :

use App\Models\Post;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;

Route::get('/posts/{post}', function (Post $post) {
    return Inertia::render('PostDetails', [
        'post' => $post,
        'can' => [
            'edit' => Gate::allows('edit', $post),
            'delete' => Gate::allows('delete', $post),
        ],
    ]);
});

Ici, Gate::allows vérifie si l’utilisateur peut exécuter une action spécifique sur le modèle, et les résultats sont transmis comme un objet can.

Utilisation dans le composant Vue.js

Dans le composant Vue.js, ces autorisations sont utilisées pour conditionner l’affichage :

<script setup>
defineProps(['post', 'can']);

function deletePost() {
  if (confirm('Are you sure you want to delete this post?')) {
    // Appel pour supprimer le post
  }
}
</script>

<template>
  <div>
    <h1 class="text-xl font-bold">{{ post.title }}</h1>
    <p class="mb-4">{{ post.content }}</p>

    <div class="flex space-x-2">
      <inertia-link
        v-if="can.edit"
        :href="`/posts/${post.id}/edit`"
        class="px-4 py-2 bg-blue-500 text-white rounded"
      >
        Edit
      </inertia-link>
      
      <button
        v-if="can.delete"
        @click="deletePost"
        class="px-4 py-2 bg-red-500 text-white rounded"
      >
        Delete
      </button>
    </div>
  </div>
</template>

Avantages

  • Centralisation des autorisations : Toute la logique d’autorisation reste gérée côté Laravel.
  • Clarté et modularité : Les permissions sont transmises explicitement, rendant le code plus lisible et maintenable.
  • Flexibilité : Cette approche permet de gérer des autorisations dynamiques basées sur des rôles, des statuts ou d’autres critères.

En transmettant les permissions comme des props, on maintient une séparation claire entre la logique métier et la présentation tout en respectant les principes d’Inertia.js.