0
0
LaravelHow-ToBeginner · 4 min read

How to Use Policy in Laravel for Authorization

In Laravel, use policies to organize authorization logic for models. Define policy classes with methods for actions, register them in AuthServiceProvider, and call $this->authorize() or Gate::allows() in controllers or views to check permissions.
📐

Syntax

A policy class contains methods that define authorization rules for a model. Each method receives the authenticated user and the model instance to check permissions.

Register policies in AuthServiceProvider by mapping models to policy classes.

Use $this->authorize('action', $model) in controllers or @can('action', $model) in Blade views to enforce policies.

php
php artisan make:policy PostPolicy --model=Post

// In AuthServiceProvider.php
protected $policies = [
    App\Models\Post::class => App\Policies\PostPolicy::class,
];

// In PostPolicy.php
public function update(User $user, Post $post) {
    return $user->id === $post->user_id;
}

// In Controller
public function update(Request $request, Post $post) {
    $this->authorize('update', $post);
    // update logic
}
💻

Example

This example shows creating a policy for a Post model that allows only the owner to update it. The policy is registered, and the controller uses $this->authorize() to check permission before updating.

php
<?php

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

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

// AuthServiceProvider.php
protected $policies = [
    \App\Models\Post::class => \App\Policies\PostPolicy::class,
];

// PostController.php
public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);
    $post->update($request->all());
    return response()->json(['message' => 'Post updated']);
}
Output
{"message":"Post updated"}
⚠️

Common Pitfalls

  • Not registering the policy in AuthServiceProvider causes authorization checks to fail silently.
  • Forgetting to pass the model instance to $this->authorize() or @can leads to incorrect permission checks.
  • Using policies for non-model actions without defining appropriate methods can cause errors.
php
<?php
// Wrong: Missing model instance
$this->authorize('update'); // Fails

// Right: Pass model instance
$this->authorize('update', $post);
📊

Quick Reference

StepDescriptionCode Example
Create PolicyGenerate policy for modelphp artisan make:policy PostPolicy --model=Post
Register PolicyMap model to policy in AuthServiceProvider'protected $policies = [Post::class => PostPolicy::class];'
Define MethodsAdd authorization methods like update, deletepublic function update(User $user, Post $post) { return $user->id === $post->user_id; }
Use PolicyCall authorize in controller$this->authorize('update', $post);
Blade CheckUse @can directive in views@can('update', $post) ... @endcan

Key Takeaways

Define policies to organize authorization logic for models in Laravel.
Register policies in AuthServiceProvider to enable Laravel to find them.
Use $this->authorize() in controllers to check permissions before actions.
Pass the model instance when calling authorization methods for accurate checks.
Use @can directive in Blade templates to conditionally show UI based on permissions.