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
AuthServiceProvidercauses authorization checks to fail silently. - Forgetting to pass the model instance to
$this->authorize()or@canleads 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
| Step | Description | Code Example |
|---|---|---|
| Create Policy | Generate policy for model | php artisan make:policy PostPolicy --model=Post |
| Register Policy | Map model to policy in AuthServiceProvider | 'protected $policies = [Post::class => PostPolicy::class];' |
| Define Methods | Add authorization methods like update, delete | public function update(User $user, Post $post) { return $user->id === $post->user_id; } |
| Use Policy | Call authorize in controller | $this->authorize('update', $post); |
| Blade Check | Use @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.