Tar*_*nis 8 laravel vue.js laravel-sanctum
我确实需要帮助来完成我尝试做的一件小事。我尝试在我的 laravel / Vue 设置中为一个用户使用并发的 individual_access_tokens 。一切工作正常,除了一件事之外,我想在用户注销时通过其 id 删除一个令牌。通过一个用户的登录,我为他们创建一个personal_access_token。注销后,应删除该特定的 access_token。
现在在我的注销方法中,我删除了所有令牌。这工作正常,但是当删除一个特定的令牌(应该有效)时,我总是收到此方法不存在的错误:
public function logout(Request $request){
Auth::guard('web')->logout();
// First try: auth()->user()->currentAccessToken()->delete();
// Second try: $request->user()->token()->revoke();
auth()->user()->tokens()->delete();
}
Run Code Online (Sandbox Code Playgroud)
错误:
LOG.error:调用未定义的方法 Laravel\Sanctum\TransientToken::delete() {"userId":18,"exception":{}}
api.php
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::post('/logout', [AuthController::class, 'logout']);
});
Run Code Online (Sandbox Code Playgroud)
我尝试了以下内容:
https://laracasts.com/discuss/channels/laravel/passport-how-can-i-manually-revoke-access-token (护照)https://laracasts.com/discuss/channels/laravel/deleting-users-注销时的护照令牌 https://divinglaravel.com/authentication-and-laravel-airlock https://laracasts.com/discuss/channels/laravel/spa-and-mobile-logout?page=1&replyId=698040
在所有这些线程中,使用的方法应该有效,但不适合我。我是否忽略了什么?
我感谢每一个帮助!
Dan*_*iro 16
关于实施的一些注意事项:
delete()and ;logout()web基于令牌的请求使用防护;attempt($credentials)基于令牌的登录;简而言之,此异常是混合 cookie 和 token 身份验证代码的指示器。
delete()andlogout()Sanctum 有两种身份验证方式:cookie 和 token。
每种类型的身份验证都需要完全不同的实现。它们不兼容。
auth('web')->logout();auth('sanctum')->user()->currentAccessToken()->delete();当执行路由时,Sanctum Guard 会检测身份验证的类型:cookie 或令牌。如果是 cookie,则返回TransientTokenon currentAccessToken()。如果它是一个令牌,则返回一个PersonalAccessToken。
因为这个决定会影响之后的一切,所以你不能混合 cookie 和令牌代码。如果您想同时接受这两种类型,则必须为每种类型创建单独的代码。
这意味着您将 cookie 身份验证路由放入 中web.php,将令牌身份验证路由放入 中api.php。
如果混合使用它们,您将获得delete method not found基于 cookie 的注销和logout method not found基于令牌的注销。
web基于令牌的请求使用防护守卫web是 的别名SessionGuard。顾名思义,它基于会话和cookie。
Laravel 自动加载路由的会话和 cookies 中间件web.php。这就是为什么您可以对路线使用“网络”守卫web.php。
Laravel 不会为api.php路由加载这些中间件。因此,我们不能web在api.php路线中使用守卫。
因此,请确保您不在web任何api.php路线上使用防护装置。
对于圣所,你可以使用sanctum守卫来代替。
另请注意,web未指定时这是默认的防护。为了安全起见,请为每个身份验证调用显式设置防护:
Auth::guard('sanctum')->...;auth('sanctum')->...;auth()->guard('sanctum')->...;attempt($credentials)基于令牌的登录许多人使用 来实现 Sanctum 登录attempt($credentials)。这对于基于令牌的身份验证来说是错误的。
应该如何:
auth('web')->attempt($credentials);如果您使用auth()->attempt($credentials),则使用“网络”防护。Web 防护使用 cookie,它在路由中不起作用api.php,也不适合基于令牌的身份验证。
如果您使用它,您可能不会收到错误,并且身份验证甚至可能有效,但它是错误的,也是您收到异常的主要原因。
不幸的是,没有auth('sanctum')->attempt($credentials),所以你必须手动实现它。
Sanctum官方文档有一个实现的片段。您只需复制并粘贴(并根据需要进行调整):
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
Route::post('/sanctum/token', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken($request->device_name)->plainTextToken;
});
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,调用auth()->user()->currentAccessToken()->delete()给出错误Call to undefined method Laravel\\Sanctum\\TransientToken::delete()。
我发现这是因为 Sanctum 身份验证守卫的工作原理。当 Laravel 会话已经就位时,通过会话 cookie,守卫会将 TransientToken 放在用户身上,然后通过currentAccessToken(). 但这TransientToken不是真实的PersonalAccessToken,也没有delete()方法。
在此处的源代码中找到了这一点。
我的解决方法是将注销路由不放在 Web 组中,而是放在 api 组中,该组不包含会话的中间件。
对于特定用户:
Auth::user()->tokens()->where('id', $id)->delete();
Run Code Online (Sandbox Code Playgroud)
对于想要注销的请求用户
$user = request()->user();
$user->tokens()->where('id', $user->currentAccessToken()->id)->delete();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17436 次 |
| 最近记录: |