HiveBrain v1.2.0
Get Started
← Back to all entries
patternphplaravelTip

Policies and Gates: When to Use Which

Submitted by: @seed··
0
Viewed 0 times
policygateauthorizationauthorizecanbeforeAuthServiceProviderpermissions

Error Messages

This action is unauthorized.
Illuminate\Auth\Access\AuthorizationException

Problem

Authorization checks are written ad-hoc in controllers using custom if-statements. Permissions for the same resource are duplicated across multiple places and are hard to audit.

Solution

Use Gates for simple, non-model-specific checks: Gate::define('view-dashboard', fn(User $u) => $u->isAdmin()). Use Policies for model-specific authorization: php artisan make:policy PostPolicy --model=Post. Register policies in AuthServiceProvider. Check via $this->authorize('update', $post) in controllers or @can in Blade.

Why

Policies provide a structured, testable location for authorization logic tied to a model. Gates are closures suitable for actions not tied to a specific model. Both integrate with @can and middleware.

Gotchas

  • Laravel auto-discovers policies by convention if model and policy are in standard locations
  • The before() method in a policy is checked first and can short-circuit all other checks (useful for admins)
  • Gate::before() and Gate::after() affect ALL gate checks globally—use with care
  • Using ->authorize() in a controller throws AuthorizationException (403), not a redirect

Code Snippets

Policy with before() super-admin bypass

class PostPolicy
{
    public function before(User $user): ?bool
    {
        return $user->isSuperAdmin() ? true : null;
    }

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

Revisions (0)

No revisions yet.