DEV3 Technologies home

DEV3 Developer Forum

Gates vs policies in Laravel: when should I use which?

Laravel helpSolved0 views
dev3 ·

I have blog posts that only the author or an admin can edit. I see Gate::define, policies, can() and @can in the docs. How do I choose and how do I wire it up so the controller returns 403 automatically?

#laravel#authorization#policies

0

1 reply

dev3 · Accepted answer

Use policies when the check is about a specific model (post, invoice, project). Use gates for model-less checks such as "can view the admin dashboard".

Policy

php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
    public function before(User $user): ?bool
    {
        return $user->is_admin ? true : null;   // null falls through to the method
    }

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

Laravel auto-discovers PostPolicy for Post in app/Policies.

Use it in the controller

public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);   // or Gate::authorize(...)
    // ...
}

A denial throws AuthorizationException, rendered as 403. In Laravel 12 the base controller does not include AuthorizesRequests any more; use Gate::authorize('update', $post) or add the trait. Route-level alternative:

Route::put('/posts/{post}', [PostController::class, 'update'])->can('update', 'post');

Gate

Gate::define('view-admin', fn (User $user) => $user->is_admin);

In Blade and code

@can('update', $post) <a href="...">Edit</a> @endcan
if ($request->user()->cannot('update', $post)) { abort(403); }

Pitfalls

  • before() returning false denies everything. Return true or null only for an admin bypass.
  • Hiding a button is not security: always authorize on the server.
  • Guests: type-hint ?User $user in the policy method to allow them.
  • For roles and permissions at scale consider spatie/laravel-permission with gates/policies on top.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.