Php 流明中间件排序(优先级)

Php 流明中间件排序(优先级),php,laravel,middleware,lumen,Php,Laravel,Middleware,Lumen,我使用的是“laravel/lumen框架”:“5.7.*” 我有两个中间件,第一个是应该应用于所有路由的authokenauthenticate,因此它在bootstrap/app.php中定义 $app->middleware([ App\Http\Middleware\AuthTokenAuthenticate::class ]); 另一个中间件的定义如下 $app->routeMiddleware([ 'auth.token' => Vendor\Ut

我使用的是
“laravel/lumen框架”:“5.7.*”

我有两个中间件,第一个是应该应用于所有路由的
authokenauthenticate
,因此它在
bootstrap/app.php
中定义

$app->middleware([
    App\Http\Middleware\AuthTokenAuthenticate::class
]);
另一个中间件的定义如下

$app->routeMiddleware([
    'auth.token' => Vendor\Utilities\Middleware\AuthToken::class
]);
只适用于某些特定路线

我需要先执行
auth.token
,然后执行
AuthTokenAuthenticate
,但我找不到方法,因为Lumen首先执行
$app->middleware
路由


Laravel拥有
$middlewarePriority
,这正是我所需要的,但我如何在Lumen中处理它呢

我认为这在流明中不可能以你想要的方式实现。我的建议是使用中间件和


删除全局中间件注册

/bootstrap/app.php

将这两个中间件添加到路由中间件

/bootstrap/app.php

创建两个路由组:一个只使用
auth.token.authenticate
,另一个组同时使用
auth.token
auth.token.authenticate

/routes/web/php

我认为这是获得所需效果的最干净的方法。

现在使用Lumen v6(可能更早),您可以在定义路由时将中间件指定为数组字段。在routes文件
web.php
中,我有如下内容:

$router->get('/api/path/to/thing', [
    'uses' => 'FooController@index',
    'middleware' => ['etag', 'caching', 'bar']
]);

注意
中间件
字段是一个包含三个元素的数组。当调用此路由时,中间件
etag
将首先执行,然后
缓存
,然后按照该顺序执行
。当您只有一个中间件类时,您可以将其指定为普通字符串或仅包含一个元素的数组。这当然可以扩展到,这样您就有了一整类路由,所有这些路由都是按这种顺序使用此中间件的。

我认为,如果不对Lumen路由代码进行大量修改,就很难做到这一点。您将看到,在第一次收集和排序所有中间件时,首先运行全局中间件,甚至在检查它是什么路由之前。关于这个问题的任何答案对您有帮助吗?因此,按照您的示例,对于第二组路由,中间件将按照以下顺序执行:首先是auth.token,然后是auth.token.authenticate?这不是一个选项,好像我将开始拥有更多需要应用于所有路由的中间件,浏览所有路由的列表并将其添加到每个路由中并不是一个好的解决方案最初的问题只提到了两个中间件。如果以后要添加越来越多的中间件,那么我同意这不是一个可行的解决方案。然而,Lumen不支持这种情况。我的建议是寻找或编写您自己的包来提供所需的功能。这在Lumen中始终是可能的,但是您只能处理命名路由,而不能处理定义为适用于所有路由的路由,如我提供的示例所示
$app->routeMiddleware([
    'auth.token' => Vendor\Utilities\Middleware\AuthToken::class,
    'auth.token.authenticate' => App\Http\Middleware\AuthTokenAuthenticate::class
]);
$router->get('/', ['middleware' => 'auth.token.authenticate', function () use ($router) {
    // these routes will just have auth.token.authenticate applied
}]);

$router->get('/authenticate', ['middleware' => 'auth.token|auth.token.authenticate', function () use ($router) {
    // these routes will have both auth.token and auth.token.authenticate applied, with auth.token being the first one
}]);
$router->get('/api/path/to/thing', [
    'uses' => 'FooController@index',
    'middleware' => ['etag', 'caching', 'bar']
]);