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
相关产品推荐
相关产品推荐

