Statamic用户需每6个月更新密码,中间件实现遇阻求助
解决Statamic中密码过期强制重置问题
针对你遇到的中间件未生效问题,可按以下步骤排查修复:
1. 确保User模型正确处理日期字段
Statamic的用户模型需要将password_updated_at转换为Carbon实例才能进行日期比较,在自定义User模型(或扩展的默认模型)中添加字段类型转换:
protected $casts = [ 'password_updated_at' => 'datetime', ];
2. 修复中间件逻辑,避免循环跳转
当前中间件会拦截所有web路由,包括密码重置页面,导致无限重定向。修改中间件代码,排除相关路由:
public function handle($request, Closure $next) { // 排除密码过期重置相关路由,防止循环 if ($request->routeIs('password.expired', 'password.update.expired')) { return $next($request); } $user = auth()->user(); if ($user && $user->password_updated_at && $user->password_updated_at->lt(now()->subMonths(6))) { return redirect()->route('password.expired'); } return $next($request); }
3. 调整中间件注册顺序
确保你的密码检查中间件在认证中间件之后执行,这样才能获取到已登录的用户信息。修改bootstrap/app.php中的注册代码:
->withMiddleware(function (Middleware $middleware) { $middleware->web([ \Statamic\Http\Middleware\Authenticate::class, \App\Http\Middleware\CheckPasswordExpiry::class, ]); })
4. 创建密码过期路由与视图
在routes/web.php中添加路由,用于展示过期提示和处理密码更新:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; // 密码过期提示页面 Route::get('/password/expired', function () { return view('auth.password-expired'); })->name('password.expired'); // 处理过期密码更新 Route::post('/password/expired', function (Request $request) { $request->validate([ 'password' => 'required|confirmed|min:8', ]); $user = auth()->user(); $user->update([ 'password' => Hash::make($request->password), 'password_updated_at' => now(), ]); return redirect()->intended('/'); })->name('password.update.expired');
创建对应的视图文件resources/views/auth/password-expired.blade.php,示例内容:
<!DOCTYPE html> <html> <head> <title>密码已过期</title> </head> <body> <h1>您的密码已过期,请重置密码</h1> <form method="POST" action="{{ route('password.update.expired') }}"> @csrf <div> <label>新密码:</label> <input type="password" name="password" required> </div> <div> <label>确认新密码:</label> <input type="password" name="password_confirmation" required> </div> <button type="submit">更新密码</button> </form> </body> </html>
5. 初始化旧用户的密码更新时间
对于数据库中已存在的用户,需要批量填充password_updated_at字段(默认值仅对新用户生效),执行SQL语句:
UPDATE users SET password_updated_at = created_at WHERE password_updated_at IS NULL;
6. 验证时区设置
确保项目时区与数据库时区一致,避免日期计算错误。修改config/app.php中的时区配置:
'timezone' => 'Asia/Shanghai', // 替换为你的实际时区
完成以上步骤后,用户登录时若密码超过6个月未更新,会被引导至密码重置页面,更新后即可正常访问系统。
内容的提问来源于stack exchange,提问作者fajriyan
相关产品推荐
相关产品推荐

