

When building applications using Laravel, controlling user access is extremely important.
For example:
- Only blog owners should edit their posts
- Only admins should delete users
- Sellers should manage only their own products
- Logged-in users can create content
Laravel provides a powerful and clean authorization system called Policies to handle these scenarios.
In this guide, you’ll learn:
- What Laravel Policies are
- Why they are important
- How to create policies
- How to use policies in controllers
- How to use policies in Blade templates
- Real-world examples
- Best practices
What Are Laravel Policies?
Laravel Policies are classes that organize authorization logic around a model.
Instead of writing permission checks directly inside controllers:
if(auth()->id() !== $blog->user_id){
abort(403);
}
Laravel allows you to centralize the logic inside a policy class.
Example:
app/Policies/BlogPolicy.php
This keeps your application:
- Clean
- Scalable
- Secure
- Easy to maintain
Why Use Policies in Laravel?
Policies help separate authorization logic from business logic.
Without Policies
Controllers become messy:
if(auth()->user()->role != ‘admin’){
abort(403);
}
Repeated everywhere.
With Policies
Controllers stay clean:
$this->authorize(‘update’, $blog);
Authorization logic stays centralized.
Real-World Example
Imagine a blog application.
| Action | Permission |
| View Blogs | Everyone |
| Create Blog | Logged-in users |
| Edit Blog | Blog owner only |
| Delete Blog | Admin only |
Policies are perfect for this scenario.
Creating a Laravel Policy
Laravel provides an artisan command to generate policy classes.
php artisan make:policy BlogPolicy –model=Blog
This command creates:
app/Policies/BlogPolicy.php
Laravel Policy Structure
Generated example:
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\Blog;
class BlogPolicy
{
public function viewAny(User $user)
{
return true;
}
public function view(User $user, Blog $blog)
{
return true;
}
public function create(User $user)
{
return true;
}
public function update(User $user, Blog $blog)
{
return $user->id === $blog->user_id;
}
public function delete(User $user, Blog $blog)
{
return $user->role === 'admin';
}
}
Understanding Policy Methods
viewAny()
Checks permission for viewing all records.
public function viewAny(User $user)
{
return true;
}
view()
Checks permission for viewing a single record.
public function view(User $user, Blog $blog)
{
return true;
}
create()
Checks permission for creating records.
public function create(User $user)
{
return true;
}
update()
Checks edit permission.
public function update(User $user, Blog $blog)
{
return $user->id === $blog->user_id;
}
Only the blog owner can edit.
delete()
Checks delete permission.
public function delete(User $user, Blog $blog)
{
return $user->role === 'admin';
}
Only admins can delete.
Registering Policies in Laravel
In modern Laravel versions, policies are auto-discovered automatically.
Manual registration example:
Open:
app/Providers/AuthServiceProvider.php
Add:
protected $policies = [
Blog::class => BlogPolicy::class,
];
Using Policies in Controllers
Laravel provides the authorize() method.
Example
public function update(Request $request, Blog $blog)
{
$this->authorize(‘update’, $blog);
$blog->update($request->all());
return response()->json([
‘message’ => ‘Updated successfully’
]);
}
Laravel automatically calls:
BlogPolicy@update
Unauthorized Access Response
If permission fails, Laravel automatically returns:
{
“message”: “This action is unauthorized.”
}
HTTP status:
403 Forbidden
Using Policies in Blade Templates
Laravel provides Blade directives for authorization.
@can Directive
@can('update', $blog)
<a href="#">Edit Blog</a>
@endcan
@cannot Directive
@cannot('delete', $blog)
<p>No permission</p>
@endcannot
Admin Override Using before()
Sometimes administrators should bypass all authorization checks.
public function before(User $user, string $ability)
{
if ($user->role === 'admin') {
return true;
}
}
Now admins automatically have full access.
Real Project Example — Product Management
Suppose sellers can update only their own products.
ProductPolicy Example
public function update(User $user, Product $product)
{
return $user->id === $product->seller_id;
}
This ensures sellers cannot edit other seller products.
Laravel Policy Folder Structure
app/
├── Policies/
│ ├── BlogPolicy.php
│ ├── ProductPolicy.php
Common Laravel Policy Methods
| Method | Purpose |
| viewAny | View all records |
| view | View single record |
| create | Create record |
| update | Edit record |
| delete | Delete record |
| restore | Restore deleted records |
| forceDelete | Permanently delete |
Laravel Gate vs Policy
| Gate | Policy |
| Simple permissions | Model permissions |
| Closure-based | Class-based |
| Small checks | CRUD authorization |
| Example: admin access | Example: blog ownership |
Gate Example
Gate::define('isAdmin', function ($user) {
return $user->role === 'admin';
});
Usage:
if (Gate::allows('isAdmin')) {
// allowed
}
Best Practices for Laravel Policies
✅ Keep authorization inside policies
✅ Avoid permission checks inside controllers
✅ Use policies for model-related authorization
✅ Use Gates for small global permissions
✅ Use before() for admin bypass
✅ Always return boolean values
✅ Keep controllers clean and readable
Benefits of Using Laravel Policies
Using Policies provides several advantages:
- Centralized authorization logic
- Cleaner controllers
- Better security
- Easier maintenance
- Scalable architecture
- Improved readability
Policies are essential for large applications and APIs.
Final Thoughts
Laravel Policies are one of the best ways to implement authorization in modern PHP applications.
Whether you’re building:
- Blog systems
- Admin dashboards
- eCommerce applications
- SaaS platforms
- REST APIs
Policies help secure your application while keeping your code clean and maintainable.
If you’re serious about building professional Laravel applications, mastering Policies is a must.
Frequently Asked Questions
Gates are used for simple authorization checks, while Policies are used for model-based CRUD authorization.
Policies are usually stored inside:
app/Policies
Yes. Policies work perfectly with Laravel APIs and are commonly used in REST API development.
Yes. When authorization fails, Laravel automatically throws a 403 Unauthorized response.
Conclusion
Laravel Policies provide a clean, secure, and scalable way to manage authorization in your applications.
By separating permission logic into dedicated classes, you can:
- Improve code quality
- Reduce duplication
- Enhance security
- Simplify maintenance
Start using Policies in your Laravel projects to build more professional and secure applications.





