You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:33:32