Authorization in Laravel is mainly handled through Policies and Gates. Policies are used to organize authorization logic around a particular model, while gates are simple closures that provide authorization for a single action.
Gates are typically defined in the AuthServiceProvider
class. A gate is simply a closure that checks if a user can perform a given action.
You can define a gate in the app/Providers/AuthServiceProvider.php
file:
use Illuminate\Support\Facades\Gate;
public function boot()
{
$this->registerPolicies();
// Define a gate to check if a user can view a post
Gate::define('view-post', function ($user, $post) {
return $user->id === $post->user_id;
});
}
To check the gate before performing an action:
if (Gate::allows('view-post', $post)) {
// The user can view the post
} else {
// The user cannot view the post
}
Policies provide a more structured way to handle authorization logic related to models. You can generate policies using Artisan commands.
Use the Artisan command to create a policy:
php artisan make:policy PostPolicy
This creates a policy class in app/Policies/PostPolicy.php
. You can define methods for various actions (view, create, update, delete).
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
Once you’ve defined your policy methods, you need to register the policy in the AuthServiceProvider
.
use App\Models\Post;
use App\Policies\PostPolicy;
public function boot()
{
$this->registerPolicies();
// Register the PostPolicy
Gate::policy(Post::class, PostPolicy::class);
}
You can now use the authorize
method to check authorization for a specific action. For example, to authorize a user before updating a post:
public function update(Post $post)
{
$this->authorize('update', $post); // This will check the 'update' method in the PostPolicy
// Proceed with the update if authorized
}
You can also use middleware to protect routes and ensure that only authorized users can access them.
Route::put('/post/{post}', [PostController::class, 'update'])
->middleware('can:update,post'); // The 'update' method from the PostPolicy will be checked
You can implement role-based authorization by adding roles to your user model and checking permissions based on these roles.
Gate::define('admin', function ($user) {
return $user->role === 'admin';
});