我已经制作了一个角色中间件来检查用户是否具有特定的角色:
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->user() === null) {
return response("Insufficient permissions", 401);
}
$actions = $request->route()->getAction();
$roles = isset($actions['roles']) ? $actions['roles'] : null;
if ($request->user()->hasAnyRole($roles) || !$roles) {
return $next($request);
}
return response("Insufficient permissions", 401);
}
}
如果我想检查特定角色中的某个角色,那很容易。我只需要添加中间件和一个名为roles
的附加操作。 E. g。:
Route::get('payments/{id}/pay', [
'uses' => 'PaymentController@aprove',
'as' => 'payments.aprove',
'middleware' => 'roles',
'roles' => [User::ADMINISTRATOR, User::SPOT_MANAGER, User::SELECTION_PROCESS_MANAGER],
]);
这样做可以按预期工作。但是,我有一些Route::resource
代替get
,post
或类似的路线。 Laravel不允许在资源中指定roles => [...]
。
文档说如果我想在资源I should do this on controller上注入中间件。但我不能像往常一样在正常路线上指定roles => [...]
!我怎么能这样做?
提前致谢。
答案 0 :(得分:1)
您可以通过使用中间件参数来避免这种情况,因此您可以将参数传递给中间件。这种'动作'方法对于某些事情来说是一个很好的工作,但中间件需要参数,所以除非你需要更多地方的参数,否则确实没有必要。
data := Person{}
c.Find(bson.M{"login": "Larry"}).One(&data)
fmt.Printf("(%v)\n", data.pass)
字面上,文档中的中间件参数示例是用户角色检查。
Laravel 5.5 Docs - Middleware - Parameters
也没有'注射'。你只是告诉路由器你想要中间件,没有任何东西注入其他任何东西。
答案 1 :(得分:1)
由于您在定义资源路由时无法控制'action'数组,并且中间件参数不合适,您可以定义自己的ResourceRegistrar
并将其绑定到容器,以便路由器使用它在Route::resource
来电。
您将扩展Illuminate\Routing\ResourceRegistrar
并覆盖getResourceAction
方法以检查$options
数组以查看是否...让我们说明了一个名为action
的密钥。如果是这样,请将此数组合并到$action
数组中,现在通过Route::resource
定义的所有路由都可以接受action
的选项键,该键可以获取额外的操作值。
允许定义如下:
Route::resource('blah', 'BlahController', [
'action' => ['roles' => ['admin', 'editor']]
]);
这样的'应该'做的事情:
protected function getResourceAction($resource, $controller, $method, $options)
{
$action = parent::getResourceAction($resource, $controller, $method, $options);
if (isset($options['action'])) {
$action += $options['action'];
}
return $action;
}
在register
的服务提供商处绑定:
$this->app->bind(
\Illuminate\Routing\ResourceRegistrar::class,
\App\Your\ResourceRegistrar::class
);
您可以更进一步,使其特定于角色,以便您可以这样做:
Route::resource('blah', 'BlahController', ['roles' => ['admin', 'editor']]);