AndySong's avatar

one confusing thing about Gates and Policies

So I was reading the laravel authorization part docs. I am really confused about how to write gates.

I understand that I can define a Gate either using closures or Class@method style callback string, like controllers. and that is going to call the policy method. and then we call Gate::allows() or Gate::()denies() to check.

However, if I only create a policy class and not to define a Gate in the service provider. I actually still can call Gate::allows() and Gate::()denies() and this still works.

Does this mean Gate::define() is redundant if I only write gates in Class@method way? or did I missing something in the doc.

Thanks

0 likes
6 replies
AndySong's avatar

and if I were to define another gate (using a different name) that points to the same method on policy class, I can use both gates....does this mean that I have two gates that point to the same thing.....

OriOn's avatar

for a single authorization "rule" you can define either a Gate or a Policy (it's only if you define both for a single ability that it becomes redundant)

the choice between one or the other only defines where the rule will be stored in your code. For Laravel it will be the same thing in the end because in the AuthServiceProvider.php your will "register" the policies:

public function boot()
    {
        $this->registerPolicies();

        //
    }

Laravel provides the Policies to improve code readability if your app contains a lot of authorization gates then you will get lost in the AuthServiceProvider.php file.

Policies allows you to store all authorization rules by category (the model)

OriOn's avatar

I happen to have several rules for a same "point" but it doesn't make it redundant either.

because different users have different "roles" the rules only lock down their own authorizations

AndySong's avatar

@ORION - thanks for ur reply, what I was trying to say is that I feel really confused if I have two "names" that do the same thing.

if I register a Policy class, Gate actually has access to all the methods in that class. what's the benefit for defining Gate in Class@method way.

I think it makes sense when defines it inside a closure. as it's like an anonymous method, we have to give it a name, otherwise, we are not able to resolve it.

AndySong's avatar

@orion oh.... does it mean that laravel wants to give us the ability to override the names? I mean we do not have to use the default method name, if we want to change another name?

OriOn's avatar
OriOn
Best Answer
Level 14

Every method inside a Policy should have its own name (its a php class).

You are not limited in the names

As an example I have a model called Action and in ActionPolicy I have

class ActionPolicy
{
    use HandlesAuthorization;

    public function create(User $user) { ... }
    public function beOwner(User $user, Action $action) { ... }
}

then later in the route/web.php

I use them via the middleware option

Route::middleware('can:create,App\Action')->group(function() { ... });

Route::middleware('can:beOwner,action')->group(function () {
    Route::get('action/{action}/edit', 'ActionController@edit')->name('owner.edit');
}

Please or to participate in this conversation.