简体   繁体   中英

Laravel 5.1 Policies in Form Requests

I'm working on Laravel 5.1, and more specifically the Authorization package.

Before this package, I would do all my authorization checks in the FormRequest::authorize() method, since this method was designed specifically for authorization checking.

I now want to use the native Authorization package in laravel, which includes Policy files, but I want to use them in the Request file.

This means, as far as I can see, that each form request file needs to be mapped to the policy file.

Surely this cannot be right? If I have 7 main methods in each controller, thats 7 mappings to a single policy file, 1 for each request file. If I then have 20 controllers, thats 140 mappings!

I know I can do that auth check in the controller, and just map the controller, but this seems to be poor implementation on Laravels behalf, otherwise why put the authorize() method in the request?

Question

In an ideal world, I want to to my policy auth checking before reaching the controller - by doing it in the request. But I don't want to map out each of my request files to a policies.

Is there any way to retrieve the target controller from the request, so that I can just have one mapping - controller -> policy, and reference the controller from the request?

Actually, I've just found out a really easy way to do it, and feel slightly stupid I didn't try it earlier!

In my AuthServiceProvider file, I had mapped out each request to the policy file, like this:

protected $policies = [
    \App\Http\Requests\Servers\Index::class => Policies\ServerPolicy::class,
    \App\Http\Requests\Servers\Create::class => Policies\ServerPolicy::class,
    \App\Http\Requests\Servers\Store::class => Policies\ServerPolicy::class,
];

And then in my authorize() method in the Request, I was doing this:

return policy($this)->index();
   or
return policy($this)->create();

However, you do not need to pass the object to the policy. Instead you can just pass the class string.

Therefore, I only need to map the controller to the policy:

protected $policies = [
    \App\Http\Controllers\Admin\Servers::class => Policies\ServerPolicy::class
];

And then just pass the controller class path to the policy function:

return policy(\App\Http\Controllers\Admin\Servers::class)->index();

So you do not need to pass the mapped object, you can pass the fully qualified class name as a string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM