Reputation: 491
There is this method authorizeResource()
which applies specific policies to all routes (except the index route). Is there a way to apply policies only on specific routes, analogous to this function:
Route::resource('photo', 'PhotoController', ['only' => [
'index', 'show'
]]);
Upvotes: 3
Views: 4030
Reputation: 3861
Despite pointed out by @JeffPucket in his answer, the only
option didn't work for me. I'm running Laravel 5.5 and what did work was the inverse logic:
public function __construct()
{
$this->authorizeResource(Photo::class, null, [
'except' => [ 'index', 'show' ],
]);
}
Notice that you should pass to that option the actions (controller's methods) you don't want to apply your policy. In this case, index
and show
will bypass the authorization middleware.
Just for comparison, here are the results from php artisan route:list
when using each option:
only
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
| | POST | comment | comment.store | App\Http\Controllers\CommentController@store | web,auth,can:create,App\Http\Controllers\Comment |
| | GET|HEAD | comment | comment.index | App\Http\Controllers\CommentController@index | web,auth,can:view,App\Http\Controllers\Comment |
| | GET|HEAD | comment/create | comment.create | App\Http\Controllers\CommentController@create | web,auth,can:create,App\Http\Controllers\Comment |
| | GET|HEAD | comment/{comment} | comment.show | App\Http\Controllers\CommentController@show | web,auth,can:view,comment |
| | PUT|PATCH | comment/{comment} | comment.update | App\Http\Controllers\CommentController@update | web,auth,can:update,comment |
| | DELETE | comment/{comment} | comment.destroy | App\Http\Controllers\CommentController@destroy | web,auth,can:delete,comment |
| | GET|HEAD | comment/{comment}/edit | comment.edit | App\Http\Controllers\CommentController@edit | web,auth,can:update,comment |
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
except
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
| | POST | comment | comment.store | App\Http\Controllers\CommentController@store | web,auth,can:create,App\Http\Controllers\Comment |
| | GET|HEAD | comment | comment.index | App\Http\Controllers\CommentController@index | web,auth |
| | GET|HEAD | comment/create | comment.create | App\Http\Controllers\CommentController@create | web,auth,can:create,App\Http\Controllers\Comment |
| | GET|HEAD | comment/{comment} | comment.show | App\Http\Controllers\CommentController@show | web,auth |
| | PUT|PATCH | comment/{comment} | comment.update | App\Http\Controllers\CommentController@update | web,auth,can:update,comment |
| | DELETE | comment/{comment} | comment.destroy | App\Http\Controllers\CommentController@destroy | web,auth,can:delete,comment |
| | GET|HEAD | comment/{comment}/edit | comment.edit | App\Http\Controllers\CommentController@edit | web,auth,can:update,comment |
+--------+-----------+------------------------+-----------------+------------------------------------------------+--------------------------------------------------+
As you can see above, the middleware is only applied to specific routes when using except
.
Perhaps this is a bug in the framework. But it's hard to confirm that since this option doesn't seem to be documented. Even details on authorizeResource()
method are non-existing.
Upvotes: 12
Reputation: 40861
Yes, authorizeResource
accepts an $options
array as a third parameter. Just pass null
for the second argument and the syntax for options is the same as it is for route middleware.
public function __construct()
{
$this->authorizeResource(Photo::class, null, [
'only' => ['create', 'store'],
]);
}
Upvotes: 4
Reputation: 40673
You can realistically define middleware in the controller:
public PhotoController extends Controller {
public function __construct() {
$this->middleware("can:save,photo")->only(["save","edit"]); //You get the idea
}
}
This assumes you've written a proper policy (check https://laravel.com/docs/5.4/authorization)
Upvotes: 2