Php 在控制器上注入路由操作

Php 在控制器上注入路由操作,php,laravel,controller,routing,laravel-5.5,Php,Laravel,Controller,Routing,Laravel 5.5,我制作了一个角色中间件来检查用户是否具有特定角色: namespace App\Http\Middleware; use Closure; class CheckRole { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */

我制作了一个角色中间件来检查用户是否具有特定角色:

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);
    }
}
如果我想检查某个特定角色中的某个角色,这很容易。我只需要添加中间件和一个名为
角色
的附加操作。例如:

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不允许在资源中指定
角色=>[…]

文档中说,如果我想在资源上注入中间件,我就需要。但是我不能像以前在任何地方的正常路线中那样指定
角色=>[…]
!我怎么能这样做


提前感谢。

您可以通过使用中间件参数来避免这种情况,因此您可以将参数传递给中间件。对于某些事情来说,这种“操作”方法是一种很好的解决方法,但是中间件需要参数,所以实际上没有必要,除非您在更多地方需要这些参数

'middleware' => 'roles:admin,editor,...'
实际上,文档中中间件参数的示例是用户角色检查


也没有“注射”。您只是告诉路由器您想要中间件,没有任何东西注入到其他任何东西中。

您可以通过使用中间件参数来避免这种情况,因此您可以将参数传递给中间件。对于某些事情来说,这种“操作”方法是一种很好的解决方法,但是中间件需要参数,所以实际上没有必要,除非您在更多地方需要这些参数

'middleware' => 'roles:admin,editor,...'
实际上,文档中中间件参数的示例是用户角色检查


也没有“注射”。您只是告诉路由器您想要中间件,没有任何东西注入到其他任何东西中。

因为您无法控制定义资源路由时要使用的“操作”数组,中间件参数不合适,您可以定义自己的
ResourceRegister
并将其绑定到容器,以便路由器在
Route::resource
调用中使用它

您将扩展
illighted\Routing\resourceRegistrator
并覆盖
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;
}
注册处的服务提供商中,绑定:

$this->app->bind(
    \Illuminate\Routing\ResourceRegistrar::class,
    \App\Your\ResourceRegistrar::class
);
您可以更进一步,将其特定于角色,以便您可以这样做:

Route::resource('blah', 'BlahController', ['roles' => ['admin', 'editor']]);

由于您无法控制定义资源路由时要使用的“操作”数组,并且中间件参数不合适,因此您可以定义自己的
ResourceRegister
并将其绑定到容器,以便路由器将其用于
Route::resource
调用

您将扩展
illighted\Routing\resourceRegistrator
并覆盖
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;
}
注册处的服务提供商中,绑定:

$this->app->bind(
    \Illuminate\Routing\ResourceRegistrar::class,
    \App\Your\ResourceRegistrar::class
);
您可以更进一步,将其特定于角色,以便您可以这样做:

Route::resource('blah', 'BlahController', ['roles' => ['admin', 'editor']]);

我在文档中了解到了这一点,但以这种方式传递参数很难看。除非您想创建自己的ResourceRegister,否则资源路由将走不远。我在文档中了解到了这一点,但这样传递参数是很难看的。除非你想创建自己的ResourceRegister,否则你在资源路由方面不会走得很远。