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

Laravel Sanctum:登录时清除用户旧令牌并生成新令牌的优化方案

Laravel Sanctum登录时清除用户旧令牌的最优实现

需求与问题

需要实现用户登录时,清除该用户在personal_access_tokens表中的所有旧令牌,再生成新令牌。最初尝试的代码因「Call to a member function currentAccessToken() on null」报错,后续通过直接操作数据库实现了功能,但希望使用Laravel Sanctum原生方法优化。

最初报错的登录代码

$request->validate([
    'email'    => 'required | email',
    'password' => 'required'
]);

$user = User::where('email', $request->email)->first();

if (!$user){
    return response(['payback' => 'Account not found']);
} else if(!Hash::check($request->password, $user->password)){
    return response(['payback' => 'Incorrect Credentials']);
}

if($request->user()->currentAccessToken()){
    $request->user()->currentAccessToken()->delete();
} else {
    return response(['payback' => 'Not Has Tokens']);
}

$token = $user->createToken('ribluma_access_token')->plainTextToken;

直接操作数据库的实现代码

$request->validate([
    'email'    => 'required | email',
    'password' => 'required'
]);

$user = User::where('email', $request->email)->first();

if (!$user) {
    return response(['payback' => 'Account not found']);
} else if (!Hash::check($request->password, $user->password)) {
    return response(['payback' => 'Incorrect Credentials']);
}

if (count(DB::table('personal_access_tokens')->where('tokenable_id', $user->id)->get()) > 0) {
    DB::table('personal_access_tokens')->where('tokenable_id', $user->id)->delete();
}

$token = $user->createToken('ribluma_access_token')->plainTextToken;
$response = [
    'user'  => $user,
    'token' => $token
];

return $response;

Sanctum原生优化方案

错误原因

登录场景下用户尚未通过Sanctum认证,$request->user()返回null,因此调用currentAccessToken()会触发报错。

优化代码

利用Sanctum为User模型提供的tokens关联关系,直接删除用户所有令牌,无需操作DB类:

$request->validate([
    'email'    => 'required | email',
    'password' => 'required'
]);

$user = User::where('email', $request->email)->first();

if (!$user) {
    return response(['payback' => 'Account not found']);
} else if (!Hash::check($request->password, $user->password)) {
    return response(['payback' => 'Incorrect Credentials']);
}

// 原生方法删除用户所有旧令牌
$user->tokens()->delete();

$token = $user->createToken('ribluma_access_token')->plainTextToken;
$response = [
    'user'  => $user,
    'token' => $token
];

return $response;

说明

  • $user->tokens()是Sanctum自动为User模型生成的关联查询,对应personal_access_tokens表中该用户的所有记录
  • 无需判断令牌是否存在,delete()方法在无记录时不会报错,可直接调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:45:34