Gates and Policies are used for authorization (checking if a user is allowed to perform an action)

  • Gate - Simple permission check ( Like Admin access )
  • Policy - Model based permission (Like Edit post)

Gate:

Go To app/Providers/AuthServiceProvider.php

Define Gate inside boot

<?php  use Illuminate\Support\Facades\Gate;

public function boot()
{
    Gate::define('isAdmin', function ($user) {
        return $user->role == 'admin';
    });
}
?>

Note: Only admin users are allowed.

Use Gate in Controller:

if (Gate::allows('isAdmin')) {
   echo "Access allowed";
} else {
   echo "Access denied";
}

Use Gate in Blade:

@can('isAdmin')
    <p>Admin Panel</p>
@endcan

Policy:

Create Policy

php artisan make:policy PostPolicy --model=Post

This command make a file app/Policies/PostPolicy.php

<?php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
    // View any posts
    public function viewAny(User $user)
    {
        return true;
    }
    // View single post
    public function view(User $user, Post $post)
    {
        return true;
    }
    // Create post
    public function create(User $user)
    {
        return true;
    }
    // Update post (Only owner)
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
    // Delete post (Only owner)
    public function delete(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

Only the post owner can update the post.

Register Policy:

AuthServiceProvider.php

use App\Models\Post;
use App\Policies\PostPolicy;
protected $policies = [
    Post::class => PostPolicy::class,
];

Use Policy in Controller:

use App\Models\Post;
class PostController extends Controller
{
    public function edit(Post $post)
    {
        $this->authorize('update', $post);
        return view('post.edit', compact('post'));
    }
    public function destroy(Post $post)
    {
        $this->authorize('delete', $post);
        $post->delete();
        return redirect()->back();
    }
}

User Policy in Blade:

@can('update', $post)
    <a href="{{ route('post.edit',$post->id) }}">Edit</a>
@endcan