Laravel 11中间件无法读取Auth:Auth::check()始终返回false
Laravel 11 中间件无法读取Auth信息的解决方案
问题场景
编写了用于根据用户语言切换应用语言的SetUserLanguage中间件,代码如下:
public function handle(Request $request, Closure $next): Response { if (Auth::check()) { $user = Auth::user(); $languageText = $user->language_text; $language = $this->languageMapping[$languageText] ?? 'en'; if (in_array($language, ['en', 'fr', 'de', 'it'])) { App::setLocale($language); session(['locale' => $language]); } else { App::setLocale('en'); // Default language session(['locale' => 'en']); } } else { App::setLocale(session('locale', 'en')); // Default language } return $next($request); }
在Laravel 11的app.php中通过append方式注册该中间件:
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => CheckRole::class ]); $middleware->append(SetUserLanguage::class); }) ->withExceptions(function (Exceptions $exceptions) { // })->create();
当前中间件可正常运行,但Auth::check()始终返回false,Auth::user()为null,session功能正常。
问题原因
Laravel 11中,append方法会将中间件加入全局中间件栈的末尾,而认证相关的核心中间件(如StartSession、AuthenticateSession)是在web路由组的专属中间件栈中执行的。全局中间件执行时,用户认证流程还未完成,因此无法读取到Auth信息。
解决方案
方法1:将中间件添加到web路由组的中间件栈
修改app.php中的中间件配置,把SetUserLanguage添加到web路由组的中间件列表,确保它在认证中间件之后执行:
->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => CheckRole::class ]); // 替换原append操作,改为向web组追加中间件 $middleware->web(append: [ SetUserLanguage::class ]); })
方法2:全局中间件中调整执行顺序(不推荐)
如果必须让中间件全局生效,需手动确保它在认证相关中间件之后执行。但这种方式可能导致重复加载中间件,仅作备选:
->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => CheckRole::class ]); $middleware->append([ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\Auth\Middleware\AuthenticateSession::class, SetUserLanguage::class, ]); })
验证
修改配置后重新请求页面,Auth::check()将正确返回用户登录状态,Auth::user()可获取到当前用户对象,中间件会根据用户的language_text字段自动切换应用语言。
内容的提问来源于stack exchange,提问作者m.Sarto
相关产品推荐
相关产品推荐

