问题
I have a resource named Post. Every Post is related to a single User, and a User may have several (or zero) Posts.
I'm using Route::resource to map routes for every possible action on the Post resource to a single resource controller, PostController.
Now, I wish to implement a policy for the Post resource. Aiming to keep everything as simple and fool-proof as possible, I'd like to make the policy as follows:
- Every user is authorized to make any action that doesn't require an existing
Post(e.g. create). - A
Useris only authorized to access its ownPostsfor every action that accesses aPost(e.g. edit, update, delete).
What I'm trying to do right now is to create a single policy method called access, which would check that the Post is owned by the User. Then, in my PostController, every method that has a Post object in its parameters (such as edit(Post $post)) would begin with
$this->authorize('access', $post);
However, I don't like that I need to put those lines manually. If I ever forget one of those, I'll have a security hole right there.
On the other hand, I have the authorizeResource method, which makes authorization automatic but requires the policy to have several methods so they are mapped to the each of the controller's methods. Also, I tried to use the Authorize/can middleware, but it didn't work (maybe because I used it on a Route::resource mapping).
The question is: What would be the cleanest and more secure way to achieve the result I described (i.e. authorizing every possible action that accesses a resource with the exact same rule)?
回答1:
You can use authorizeResource() and override the resourceAbilityMap() method in your controller. The latter method returns a mapping from controller methods to the policy methods that will be called.
https://github.com/laravel/framework/blob/5.7/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php#L105
E.g.
class MyController extends Controller
{
// ...
/**
* Get the map of resource methods to ability names.
*
* @return array
*/
protected function resourceAbilityMap()
{
return [
'edit' => 'access',
'update' => 'access',
'destroy' => 'access',
];
}
// ...
}
来源:https://stackoverflow.com/questions/52765749/using-a-single-policy-method-to-cover-every-action-on-a-resource