Laravel Policy-Based Authorization: Creation, Registration, and Usage Guide
This article explains how Laravel's policy-based authorization works, covering policy creation, registration, usage in controllers and Blade, custom methods, response handling, guest user support, and testing, with full code examples for implementing secure and maintainable access control.
Laravel's policy-based authorization feature provides a concise and powerful solution for handling complex permission issues in applications. It allows you to encapsulate and organize authorization logic for specific models or resources, improving code maintainability and readability.
Creating a Policy
To create a policy, use the Artisan command:
php artisan make:policy PostPolicy --model=PostThis generates a policy class with stub methods for various actions:
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
public function viewAny(User $user)
{
//
}
public function view(User $user, Post $post)
{
//
}
public function create(User $user)
{
//
}
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
// other methods...
}Registering the Policy
Register your policy in AuthServiceProvider :
protected $policies = [
Post::class => PostPolicy::class,
];Using Policies in Controllers
You can authorize actions directly in a controller method:
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// update logic...
}Or use the @can directive in Blade templates:
@can('update', $post)
Edit Post
@endcanPolicy Filters
For application‑wide rules, add a filter in AuthServiceProvider :
public function boot()
{
Gate::before(function ($user, $ability) {
if ($user->isAdministrator()) {
return true;
}
});
}Resource Controllers
When using a resource controller, authorize actions in the constructor:
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}Custom Policy Methods
You can define custom methods in a policy, such as a publish check:
public function publish(User $user, Post $post)
{
return $user->role === 'editor' && !$post->is_published;
}Use the custom method like this:
if ($user->can('publish', $post)) {
// publish the post...
}Policy Responses
Policies can return more than boolean values, allowing custom responses:
public function view(User $user, Post $post)
{
if ($post->is_draft && $user->id !== $post->user_id) {
return Response::deny('You cannot view draft posts.', 403);
}
return Response::allow();
}Guest Users
For unauthenticated users, you can type‑hint a nullable user:
public function view(?User $user, Post $post)
{
return $post->is_published;
}Testing Policies
You can easily test your policies with Laravel's testing utilities:
use Illuminate\Support\Facades\Gate;
public function test_user_can_update_own_post()
{
$user = User::factory()->create();
$post = Post::factory()->create(['user_id' => $user->id]);
$this->assertTrue(Gate::forUser($user)->allows('update', $post));
}Laravel's policy-based authorization mechanism offers a clean and organized way to build complex permission systems. By encapsulating authorization logic in policy classes, you can create more maintainable, secure applications and easily adapt to evolving business rules and user roles.
PHP Practical
Scan the QR code to receive free learning materials
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.