13

I'm using "laravel/lumen-framework": "5.7.*"

I have two middlewares, first one AuthTokenAuthenticate that should be applied to all the routes, so its defined in bootstrap/app.php like

$app->middleware([
    App\Http\Middleware\AuthTokenAuthenticate::class
]);

Another middleware is defined like

$app->routeMiddleware([
    'auth.token' => Vendor\Utilities\Middleware\AuthToken::class
]);

and will only be applied to some specific routes.

I need auth.token to be executed first, then AuthTokenAuthenticate but I can't find the way to do it because Lumen executes $app->middleware routes first.

Laravel has $middlewarePriority which is exactly what I need, but how can I handle it in Lumen?

Seva Kalashnikov
  • 4,262
  • 2
  • 21
  • 36
  • I don't think this can be easily done without tinkering with the Lumen routing code quite a bit. You'll see that while [Laravel](https://github.com/laravel/framework/blob/7b074c1ac506c1895f85ec77481b55228a122a05/src/Illuminate/Routing/Router.php#L669) first gathers and sorts all the middleware, [Lumen](https://github.com/laravel/lumen-framework/blob/1fdf03d85447d9ab964eac1dd5f613d346e2be9b/src/Concerns/RoutesRequests.php#L161) first runs the global middleware before even checking what route it is. – D Malan Dec 20 '19 at 13:38
  • Does any of the answers on this question help you? https://stackoverflow.com/questions/31065936/how-to-set-the-laravel-middleware-order-of-execution – Zhephard Dec 20 '19 at 15:47

2 Answers2

5

I don't think this is possible in Lumen in the way you want to. What I suggest is using the middleware alongside the router group middleware options.


Remove the global middleware registration

/bootstrap/app.php

$app->middleware([
    //App\Http\Middleware\AuthTokenAuthenticate::class
]);

Add both middlewares to the route middleware

/bootstrap/app.php

$app->routeMiddleware([
    'auth.token' => Vendor\Utilities\Middleware\AuthToken::class,
    'auth.token.authenticate' => App\Http\Middleware\AuthTokenAuthenticate::class
]);

Create two route groups: one with just auth.token.authenticate and one group with both auth.token and auth.token.authenticate.

/routes/web/php

$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
}]);

I think this is the cleanest way to get the desired effect.

cytsunny
  • 4,838
  • 15
  • 62
  • 129
  • So, following your example, for the second group of route, is that the middleware will be execute in the order of first auth.token, then auth.token.authenticate? – cytsunny Dec 23 '19 at 04:34
  • This is not an option as if I will start having more middlewares that needs to be applied to all the routes, going thru a list of all routes and adding it to each one wouldnt be a good solution – Seva Kalashnikov Dec 25 '19 at 21:44
  • The initial problem mentioned just two middleware. If you are going to be adding more and more middleware later on then I agree it is not a workable solution. However, Lumen doesn't offer any support for this situation. My suggestion would be to either look for or write your own package which offers the needed functionality. – Govert Verschuur Dec 27 '19 at 12:52
0

As of now with Lumen v6 (and possibly earlier), you can specify the middleware as an array field when defining your route. In the routes file web.php, I have something like the following:

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

Note how the the middleware field is an array with three elements. When this route is called, the middleware etag will execute first, then caching, then bar, in that order. When you only have a single middleware class, you can either specify it as a plain string or an array with just one element. This can of course be extended to route groups so that you have an entire class of routes that all use this middleware in this order.

The Unknown Dev
  • 3,039
  • 4
  • 27
  • 39
  • This was always possible with Lumen, however you can only deal with named routes and not the ones defined to apply to all routes like in example I provided – Seva Kalashnikov Feb 21 '20 at 17:25