vincent15000's avatar

Gates and policies to manage authorizations

Hello,

With Laravel, it's possible to manage authorizations with gates and/or policies.

But what is the real difference between a gate and a policy ?

Here is an example of how I use both.

Can you simply tell me what you think about it ?

I have defined roles and each role has some permissions. Then it's possible to assign roles to users and eventually permissions directly to users, but it's better to assign only roles to keep always the same logic.

To define all permissions, I'm using gates with Gate::define(). So I can for example define a gate to check if a user is authorized to delete a task.

Gate::define('delete-task', function (User $user) { ... });

And for handling authorizations according to the business logic itself, for example a task can be deleted only if it has been completed, I'm using the policies.

public function delete(User $user, Task $task)
{
	return $task->is_completed === true;
}

But I also want that the user is authorized to trigger the action of deleting a task.

public function delete(User $user, Task $task)
{
	return $user->can('delete-task') && $task->is_completed === true;
}

Thanks for sharing how you are using gates and policies.

V

0 likes
6 replies
vincent15000's avatar

Thank you, yes I have already read the Laravel documentation for authorization.

Well ... is it possible to register custom authorizations only with policies ? so without gates ?

Sure I can create additional functions inside the policies, but policies seem to be systematically binded to models.

Whereas gates can be defined without any model.

Glukinho's avatar

I imagine this: Gate defines authorization rule over the whole app: can a user use some functionality?

Policy is more specific, it defines authorization rule over a model: can a user do some action with a model?

1 like
jlrdw's avatar

I generally do checking at method level, but of course I have auth routes to ensure they are logged in.

auth is used already in laravel so I have a authi class and:

Method level:

        if (!Authi::check('admin')) {
            return redirect(Wherever you need to here);
        }

       // Here the method is done if authorized.

The check:

    public static function check($role = null)
    {
        $userrole = Auth::user()->role;
        $checkrole = explode(',', $userrole);
        if (in_array($role, $checkrole)) {
            return true;
        }
        return false;
    }

Simplified here as there are several other functions depending on the controller method.

For a user to edit their own data I use query scopes.

Edit:

Though policies cover a model, gates can be more flexible in a complex app, as example see:

https://laravel.com/docs/12.x/authorization#inline-authorization

Straight and to the point. It actually follows the KISS principle.

1 like
Snapey's avatar
Snapey
Best Answer
Level 122

I think of it like

  • Gate = can you do something

  • Policy = can you do something with a specific object

Policy can use gates to simplify the policy.

2 likes

Please or to participate in this conversation.