[Laravel11] What to do when null or false is obtained in Auth Facade during Middleware processing [Auth::]
table of contents
Hello, this is Enoki from the System Development Department.
This time, we will be talking about the notation changes surrounding middleware with the release of Laravel 11. Many Laravel users may be aware of a change in which when adding self-made middleware, it is now written in bootstrap/app.php
instead of Kernel.php
using Auth in arbitrarily added middleware was null or false, and
there were cases where the intended result could not be obtained. I would like to write a comparison.
Example of arbitrarily created Middleware that you want to add
I want to add middleware like this! This is for those who say.
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpFoundation\Response; class HogeMiddleware { /** * Handle an incoming request. * * @ param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { $user = Auth::user() ; // If you want to redirect a specific route if a specific flag of the user is false if ($user->someThingFlag === false) { return redirect()->route('route.something'); } return $next($request); } }
(This is just an example. Please keep in mind that an error will occur if the user cannot retrieve it.)
How to add Middleware: Differences between Laravel 10 and 11
When adding any middleware in Laravel 10, you add it to $routeMiddleware in Kernel.php
/** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array<string, class-string|string> */ protected $routeMiddleware = [ 'hoge' => \App\Http\Middleware\HogeMiddleware::class, ];
At this time, I was able to use the Auth facade in the middleware without any problems. (Self-compared)
(I think there are often times when it would be nice to be able to use Auth with middleware.)
So, in Laravel 11, the part corresponding to Kenel.php was changed to app.php, and what happened to the contents is as follows.
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health : '/up', then: function () { Route::middleware([ 'web', HogeMiddleware::class, ]); } ) ->withMiddleware(function (Middleware $middleware) { $middleware->web(prepend : [ HogeMiddleware::class, ]); }) ->withExceptions(function (Exceptions $exceptions) { // })->create();
It will look like this. It feels like I've retrained myself quite a bit.
Honestly, I'm still not used to it.
If you use this as is, even if you use the Auth facade, you won't be able to get null or false information, or anything related to the authenticated user (or anything).
Solution (main topic)
This was also common in Laravel 10, but it is to set the priority.
In Laravel 10, the default middleware was grouped as shown below.
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\ View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ...
Until Laravel 10, default middleware was grouped in $middlewareGroups.
In addition, the execution order of arbitrarily created middleware could be changed arbitrarily by setting $middlewarePriority.
After this standard middleware was executed, the arbitrarily created middleware that was registered was executed, so I didn't really care about it.
When I checked, I found that the following two middlewares needed to be executed in advance in order to access user information using Auth.
\Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class,
If you use Auth in the middleware before executing these two, it seems that you cannot retrieve the information as intended.
For this reason, starting with laravel 11, priority can be set to actively control the execution order of middleware.
->withMiddleware(function (Middleware $middleware) { $middleware->priority([ \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\HogeMiddleware ::class, ]); $middleware->web(prepend: [ HogeMiddleware::class, ]); })
The Auth facade is now ready and we can retrieve data about our users.
The end
There is no particular tightening.
To be honest, when I was in version 10, I knew that I could control the execution order of middleware, but I didn't actively control it.
You can understand it by reading the official documentation, but I wanted to see more articles like Japanese articles for Laravel 11, so I wrote this.