如何在Laravel Sanctum中无需密码登出所有设备?
解决Laravel Sanctum SPA登出时强制用户所有设备下线的问题
要实现SPA用户登出时无需验证密码就强制所有设备下线,核心是同时清理用户的所有API令牌和所有会话记录,具体步骤如下:
1. 确保Session驱动为数据库(或Redis)
Laravel默认的file会话驱动无法通过用户ID关联会话,所以必须切换到database或redis驱动:
- 修改
.env文件:SESSION_DRIVER=database - 如果还没生成会话表,执行迁移:
php artisan session:table,然后php artisan migrate
2. 登出逻辑中批量清理令牌和会话
在你的登出控制器(比如LogoutController)中,同时处理令牌删除和全设备会话清理:
use Illuminate\Http\Request; public function logout(Request $request) { // 删除当前用户的所有API令牌(覆盖API和SPA的令牌认证) $request->user()->tokens()->delete(); // 删除该用户在所有设备上的会话记录 \DB::table('sessions')->where('user_id', $request->user()->id)->delete(); // 清除当前请求的会话并重新生成CSRF令牌 $request->session()->invalidate(); $request->session()->regenerateToken(); return response()->json(['message' => '已从所有设备登出'], 200); }
3. 可选:封装会话清理逻辑到用户模型
为了代码更整洁,可以在User模型中封装清理所有会话的方法:
// App\Models\User.php public function revokeAllSessions() { return \DB::table('sessions')->where('user_id', $this->id)->delete(); }
之后在登出控制器中直接调用:
$request->user()->revokeAllSessions();
原理说明
- Sanctum的SPA认证依赖Laravel的会话系统,每个设备的会话都会在
sessions表中生成一条关联用户ID的记录; - 批量删除该用户的所有会话记录后,其他设备的用户在下次发起请求时,会因为会话不存在被判定为未认证,从而强制跳转登录;
- 同时删除所有API令牌可以确保基于令牌的API认证也失效,覆盖所有认证场景。
内容的提问来源于stack exchange,提问作者Chitholian
相关产品推荐
相关产品推荐

