Laravel会话问题:自定义404后Flash消息及验证提示失效
看起来你遇到的问题根源在于会话中间件的重复加载,导致Flash消息和验证错误无法正常存储和读取。让我一步步拆解问题并给出解决办法:
为什么会出现这个问题?
Laravel 默认将会话相关的中间件(EncryptCookies、AddQueuedCookiesToResponse、StartSession)放在 web 中间件组中,只有通过 routes/web.php 定义的路由才会自动应用这些中间件。当你把它们加到全局的 $middleware 数组后,每一个请求(包括API请求、静态资源请求等)都会执行一遍这些中间件,而 web 组里的同名中间件又会再执行一次——这就导致会话被重复初始化,之前存储的Flash消息和验证错误数据被清空,自然就失效了。
解决方案
步骤1:恢复全局中间件配置
首先把你加到 $middleware 数组里的会话相关中间件移除,恢复成默认的全局中间件:
// app/Http/Kernel.php protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
步骤2:在错误处理中手动启动会话(解决Auth检查失效的问题)
之前你在 Handler.php 中无法使用 Auth::guard('org')->check(),是因为错误触发时会话还没启动。我们可以在检查Auth状态前,手动启动会话,这样既不会影响正常请求的会话流程,又能在错误处理时访问会话数据:
修改 app/Exceptions/Handler.php 中的代码:
if($exception instanceof NotFoundHttpException){ // 手动启动会话(如果还没启动的话) if (!app('session')->isStarted()) { app('session')->start(); } if(Auth::guard('org')->check() == false){ return response()->view('errors.web-404', [], 404); } }
步骤3:确认web路由的中间件配置
默认情况下,routes/web.php 中的路由已经通过 RouteServiceProvider 自动应用了 web 中间件组,你可以确认一下这个配置是否正常:
// app/Providers/RouteServiceProvider.php public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); } protected function mapWebRoutes() { Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); }
这样调整后,你的404页面会正常根据Auth状态展示,同时Flash消息和验证错误也能正常工作了——因为会话中间件只会在web请求中执行一次,不会重复初始化会话。
内容的提问来源于stack exchange,提问作者Rahul Sharma

