Laravel Policies Explained — Complete Beginner Guide

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.