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

Laravel基于Token的API中如何替代Session Storage存储密码确认状态?

Laravel API令牌认证场景下替代Session存储密码确认状态的最优方案

Laravel默认的密码确认依赖Session是为了Web端有状态场景,API令牌认证无Session的场景下,只需要把密码确认的时间戳和用户/用户当前登录令牌绑定,存储到服务端即可。


最优方案:缓存存储

该方案无需修改表结构,利用缓存自动过期特性适配密码确认的短时效属性,改造成本最低,也支持多端状态隔离。

实现步骤

  1. 修改密码确认存储逻辑
    把原Session写入代码替换为缓存写入,如果需要实现多端状态隔离(Electron端、Web端、多设备登录状态互不影响),可以把当前访问令牌的ID拼入缓存键:
if ($confirmed) {
    // 通用版本:同用户所有端共享密码确认状态
    // cache()->put("auth.password_confirmed_at.{$request->user()->id}", time(), 10800);
    
    // 端隔离版本:仅当前登录令牌生效,更适配多端使用场景
    $tokenId = $request->user()->currentAccessToken()->id;
    cache()->put("auth.password_confirmed_at.{$request->user()->id}.{$tokenId}", time(), 10800);
}

其中10800是Laravel默认的密码确认有效期(3小时),可根据业务需求自行调整。

  1. 修改密码确认校验逻辑
    把原从Session读取的逻辑替换为从缓存读取:
// 对应通用版本的校验逻辑
// $passwordConfirmedAt = cache()->get("auth.password_confirmed_at.{$request->user()->id}", 0);

// 对应端隔离版本的校验逻辑
$tokenId = $request->user()->currentAccessToken()->id;
$passwordConfirmedAt = cache()->get("auth.password_confirmed_at.{$request->user()->id}.{$tokenId}", 0);

if (time() - $passwordConfirmedAt < 10800) {
    // 密码确认有效,执行业务放行逻辑
}
  1. 补充状态失效逻辑
    在用户修改密码、主动登出时,主动删除对应的缓存,避免状态残留:
// 登出时清理缓存示例
$tokenId = $request->user()->currentAccessToken()->id;
cache()->forget("auth.password_confirmed_at.{$request->user()->id}.{$tokenId}");

可选替代方案:数据库存储

如果担心缓存丢失导致状态异常,可以给users表新增password_confirmed_at timestamp字段,密码确认成功时更新该字段,校验时读取该字段计算时间差即可。该方案状态持久化不会丢失,但不支持端隔离,且需要额外执行表迁移。

不推荐方案:JWT Payload存储

如果你的API使用JWT认证,也可以把密码确认时间戳写入JWT的Payload,但JWT本身不可变,确认密码后需要重新下发新的JWT,且无法主动失效确认状态,灵活性差,不推荐使用。


内容的提问来源于stack exchange,提问作者secondman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 04:45:02