在控制器

时间:2017-11-29 19:44:34

标签: 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
     */
    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代替getpost或类似的路线。 Laravel不允许在资源中指定roles => [...]

文档说如果我想在资源I should do this on controller上注入中间件。但我不能像往常一样在正常路线上指定roles => [...]!我怎么能这样做?

提前致谢。

2 个答案:

答案 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']]);