Laravel的password.confirm中间件设password_timeout为1后表单失效如何解决
Laravel Fortify 强制密码确认路由问题解决方案
问题根因
你将全局password_timeout配置修改为1秒后,只要用户完成密码验证后在页面停留超过1秒,后续所有带password.confirm中间件的请求(包括表单提交请求)都会被中间件拦截,直接跳转到密码确认页。跳转过程中表单提交的输入数据、控制器Request验证返回的错误信息都会被清空,因此会出现表单无响应、无错误提示的问题。
解决方案
首先将config/auth.php中的password_timeout参数改回默认值10800,不要修改全局配置影响其他业务逻辑。以下两种方案任选其一即可实现「每次访问指定路由都触发密码验证」的需求:
方案1:控制器内手动清除密码确认标记(最简方案)
在PostController的edit方法中,增加清除密码确认session标记的代码,用户每次完成验证进入编辑页后,会直接清空验证记录,下次访问该路由自动触发重新验证:
public function edit($id) { $post = \App\Models\Post::findOrFail($id); // 清除密码确认标记,下次访问强制重新验证 session()->forget('auth.password_confirmed_at'); return view('post.edit', compact('post')); }
方案2:自定义强制密码确认中间件(适用多路由复用场景)
如果多个路由都需要实现每次访问强制验证密码的逻辑,可以单独封装自定义中间件:
- 执行命令生成中间件文件
php artisan make:middleware ForcePasswordConfirm - 编辑
app/Http/Middleware/ForcePasswordConfirm.php文件,内容如下:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Redirect; class ForcePasswordConfirm { public function handle(Request $request, Closure $next, $redirectToRoute = null) { // 跳过超时判断,只要没有验证标记就触发密码确认 return $request->session()->has('auth.password_confirmed_at') ? $next($request) : Redirect::route($redirectToRoute ?: 'password.confirm'); } }
- 注册中间件,打开
app/Http/Kernel.php,在$routeMiddleware数组中追加配置:
protected $routeMiddleware = [ // 原有其他中间件 'force.password.confirm' => \App\Http\Middleware\ForcePasswordConfirm::class, ];
- 修改原有路由的中间件配置:
Route::get('/{id}/edit',[PostController::class,'edit'])->name('post.edit')->middleware('force.password.confirm');
注意事项
如果你的编辑表单提交对应的POST/PUT路由也添加了password.confirm中间件,需要将该中间件移除,或者同步使用上述自定义中间件,避免提交请求时被拦截导致数据丢失。
内容的提问来源于stack exchange,提问作者Gustavo Mur
相关产品推荐
相关产品推荐

