DEV Community

Cover image for When to Use Gates, Policies, and the Spatie Permission Package in Laravel

When to Use Gates, Policies, and the Spatie Permission Package in Laravel

“Good code is its own best documentation.”
— Steve McConnell

Key Takeaways

  • Learn what Gates, Policies, and Spatie Permission are.
  • Understand when to choose each.
  • See step-by-step examples.
  • Apply everything in one clear practical scenario.

Index

  1. What is Authorization in Laravel?
  2. When Should You Use Gates?
  3. When Should You Use Policies?
  4. When Should You Use Spatie Permission?
  5. Example Code: Gates
  6. Example Code: Policies
  7. Example Code: Spatie Permission
  8. Practical Example: A Blogging Platform
  9. Stats
  10. Interesting Facts
  11. FAQs
  12. Conclusion

1. What is Authorization in Laravel?

Authorization determines what a user can do — unlike authentication (who the user is).

Laravel provides:

  • Gates (simple closures to allow/deny actions)
  • Policies (classes that group rules for a model)
  • Integration with packages like Spatie Permission for advanced role and permission management.

2. When Should You Use Gates?

Use Gates when:

  • You need quick, simple checks.
  • Your rule doesn’t depend on Eloquent models.

Example:
“Is the user an admin?”
“Does the user have a verified email?”

3. When Should You Use Policies?

Use Policies when:

  • Your rules are about a specific model (like Post, Order, Product).
  • You want organized, reusable logic.

Example:
“Does this user own this post?”
“Can the user delete this order?”

4. When Should You Use Spatie Permission?

Use Spatie Permission when:

  • You want Role-Based Access Control (RBAC) or Permission-Based Access Control.
  • You need to manage roles and permissions dynamically (e.g., via an admin UI).
  • Your app has multiple user types (admins, editors, moderators, etc).

5. Example Code: Gates

How to define a Gate:

In AuthServiceProvider.php:

use Illuminate\Support\Facades\Gate; public function boot() { $this->registerPolicies(); Gate::define('access-admin', function ($user) { return $user->is_admin; }); } 
Enter fullscreen mode Exit fullscreen mode

How to use:

In Controller:

if (Gate::allows('access-admin')) { // Allow } else { abort(403); } 
Enter fullscreen mode Exit fullscreen mode

In Blade:

@can('access-admin') <a href="/admin">Admin Dashboard</a> @endcan 
Enter fullscreen mode Exit fullscreen mode

6. Example Code: Policies

Generate a Policy:

php artisan make:policy PostPolicy - model=Post 
Enter fullscreen mode Exit fullscreen mode

Define logic:

public function update(User $user, Post $post) { return $user->id === $post->user_id; } 
Enter fullscreen mode Exit fullscreen mode

How to use:

In Controller:

$this->authorize('update', $post); 
Enter fullscreen mode Exit fullscreen mode

In Blade:

@can('update', $post) <button>Edit Post</button> @endcan 
Enter fullscreen mode Exit fullscreen mode

7. Example Code: Spatie Permission

Installation:

composer require spatie/laravel-permission 
Enter fullscreen mode Exit fullscreen mode
php artisan vendor:publish - provider="Spatie\Permission\PermissionServiceProvider" 
Enter fullscreen mode Exit fullscreen mode
php artisan migrate 
Enter fullscreen mode Exit fullscreen mode

Assign Roles & Permissions:

use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; $permission = Permission::create(['name' => 'edit articles']); $role = Role::create(['name' => 'admin']); $role->givePermissionTo('edit articles'); $user->assignRole('admin'); 
Enter fullscreen mode Exit fullscreen mode

Usage:

In Controller:

if ($user->can('edit articles')) { // Allow } 
Enter fullscreen mode Exit fullscreen mode

In Blade:

@can('edit articles') <button>Edit Article</button> @endcan 
Enter fullscreen mode Exit fullscreen mode

8. Practical Example: A Blogging Platform

Let’s see the same scenario implemented with each method, so you get a side-by-side comparison.

Scenario
Users can create posts.
Each post has an author_id.
Only the author or an admin can delete a post.

“Your work is going to fill a large part of your life, so love what you do.”
— Steve Jobs

With Gates
Definition:

Gate::define('delete-post', function ($user, $post) { return $user->id === $post->user_id || $user->is_admin; }); 
Enter fullscreen mode Exit fullscreen mode

Controller:

if (Gate::allows('delete-post', $post)) { $post->delete(); } else { abort(403); } 
Enter fullscreen mode Exit fullscreen mode

Blade:

@can('delete-post', $post) <button>Delete Post</button> @endcan 
Enter fullscreen mode Exit fullscreen mode

With Policies
Generate Policy:

php artisan make:policy PostPolicy - model=Post 
Enter fullscreen mode Exit fullscreen mode

Define in Policy:

public function delete(User $user, Post $post) { return $user->id === $post->user_id || $user->is_admin; } 
Enter fullscreen mode Exit fullscreen mode

Controller:

$this->authorize('delete', $post); $post->delete(); 
Enter fullscreen mode Exit fullscreen mode

Blade:

@can('delete', $post) <button>Delete Post</button> @endcan 
Enter fullscreen mode Exit fullscreen mode

With Spatie Permission
Setup:

composer require spatie/laravel-permission 
Enter fullscreen mode Exit fullscreen mode
php artisan vendor:publish - provider="Spatie\Permission\PermissionServiceProvider" 
Enter fullscreen mode Exit fullscreen mode
php artisan migrate 
Enter fullscreen mode Exit fullscreen mode

Assign Role and Permission:

$permission = Permission::create(['name' => 'delete posts']); $role = Role::create(['name' => 'admin']); $role->givePermissionTo('delete posts'); $user->assignRole('admin'); 
Enter fullscreen mode Exit fullscreen mode

Controller:

if ($user->can('delete posts')) { $post->delete(); } else { abort(403); } 
Enter fullscreen mode Exit fullscreen mode

Blade:

@can('delete posts') <button>Delete Post</button> @endcan 
Enter fullscreen mode Exit fullscreen mode

“Software innovation, like almost every other kind of innovation, requires the ability to collaborate and share ideas.”
— Bill Gates

9. Stats

10. Interesting Facts

11. FAQs

Q: Can I mix Gates, Policies, and Spatie?
A: Yes — many projects use them together.

Q: Are Policies required for Spatie?
A: No — but you can combine them.

12. Conclusion

Here’s a recap:

  • Gates: Small, quick checks.
  • Policies: Organized model rules.
  • Spatie Permission: Powerful RBAC and permissions.

About the Author: Vatsal is a web developer at AddWebSolution. Building web magic with Laravel, PHP, MySQL, Vue.js & more. Blending code, coffee, and creativity to bring ideas to life.

Top comments (0)