Skip to main content

Authorization with Gates and Policies

19/28
Chapter 5 Authentication and Authorization

Authorization with Gates and Policies

24 min read Lesson 19 / 28

Fine-Grained Authorization

Authentication answers "who are you?" Authorization answers "what are you allowed to do?" Laravel provides Gates and Policies.

Policies (Preferred Approach)

php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
    public function viewAny(User $user): bool
    {
        return true;
    }

    public function view(?User $user, Post $post): bool
    {
        return $post->is_published || $user?->id === $post->user_id;
    }

    public function create(User $user): bool
    {
        return $user->hasVerifiedEmail();
    }

    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id || $user->isAdmin();
    }
}

Register in AppServiceProvider:

Gate::policy(Post::class, PostPolicy::class);

Using Policies

// In controllers
public function update(UpdatePostRequest $request, Post $post): RedirectResponse
{
    $this->authorize('update', $post);
    $post->update($request->validated());
    return redirect()->route('posts.show', $post);
}

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

@can('delete', $post)
    <form method="POST" action="{{ route('posts.destroy', $post) }}">
        @csrf @method('DELETE')
        <button>Delete</button>
    </form>
@endcan

Gates for Simple Checks

// In AppServiceProvider
Gate::define('admin-access', function (User $user) {
    return $user->role === 'admin';
});

// Usage
if (Gate::allows('admin-access')) {
    // Admin-only logic
}

@can('admin-access')
    <a href="/admin">Admin Panel</a>
@endcan

Policies keep authorization organized, testable, and co-located with the model they protect.