thc1967's avatar

Lumen is applying Middleware to all Routes

I thought I followed the documentation on this, but it doesn't seem to be working as I expect it to. Using Lumen 5.4, I've created a "basic authentication" Middleware that I applied to a single route. However, when I visit any route, the browser asks for authentication.

app.php

$app->routeMiddleware([
    'auth.basic' => \App\Http\Middleware\BasicAuthMiddleware::class
]);

Added the middleware reference to app->routeMiddleware() which I thought means I had to apply it a route at a time.

web.php

$app->get('/Members/', function () {
    return response()->json(Member::all(), 200, [], JSON_PRETTY_PRINT);
});

$app->post('/getData/', function (Request $r) use ($app) {
    // Way too much logic for a closure, but that isn't the point of this post
    return response()->json($responseArray, 200, [], JSON_PRETTY_PRINT);
})->middleware('\App\Http\Middleware\BasicAuthMiddleware::class');

In the two examples from my web.php file above, one (GET /Members) should have no Middleware applied and one (POST /getData) should.

However, when I browse to mysite/Members, the browser asks for authentication.

What did I do wrong?

0 likes
5 replies
agCepeda's avatar

You should check the global middleware if it doesn't exist there.

thc1967's avatar

There's no global middleware.

I think it has something to do with this in my web.php:

$app->post('/getData/', function (Request $r) use ($app) {
    // Way too much logic for a closure, but that isn't the point of this post
    return response()->json($responseArray, 200, [], JSON_PRETTY_PRINT);
})->middleware('\App\Http\Middleware\BasicAuthMiddleware::class');

If I do this instead, it works as I expect:

$app->post('/getData/', ['middleware' => 'auth.basic', function (Request $r) use ($app) {
    // Way too much logic for a closure, but that isn't the point of this post
    return response()->json($responseArray, 200, [], JSON_PRETTY_PRINT);
}]);

Therefore, my assumption is that adding ->middleware(...) onto the $app-post() call somehow applies that middleware to all routes.

Feels like it could be a bug in Laravel / Lumen, but maybe it's expected behavior and I just haven't learned the platform well enough to recognize that yet.

thc1967's avatar

If I recall correctly, the only things I changed in app.php from the OOTB Lumen 5.4 was to un-comment withFacades() and withEloquent() and add the lines in my original post.

Here's the whole file with comments removed:

<?php

require_once __DIR__.'/../vendor/autoload.php';

try {
    (new Dotenv\Dotenv(__DIR__.'/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

$app = new Laravel\Lumen\Application(
    realpath(__DIR__.'/../')
);

$app->withFacades();

$app->withEloquent();

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->routeMiddleware([
    'auth.basic' => \App\Http\Middleware\BasicAuthMiddleware::class
]);

$app->register(App\Providers\AppServiceProvider::class);


$app->group(['namespace' => 'App\Http\Controllers'], function ($app) {
    require __DIR__.'/../routes/web.php';
});

return $app;
thc1967's avatar
thc1967
OP
Best Answer
Level 8

All right, so it looks like $app->post() winds up calling RoutesRequests::post(), which returns an object that implements ReoutesRequests. Therefore when I do $app->post()->middleware(), it is effectively calling RoutesRequests::middleware(), which adds the Middleware to all the routes served by the same RoutesRequests object.

That is why using the ->middleware() approach associated the auth.basic middleware with all routes and why using the $app->post('', ['middleware' => 'auth.basic', function... approach associates the middleware with only the specific route.

Please or to participate in this conversation.