我目前正在使用2个项目。 1个前端(使用laravel后端与API通信)和另一个laravel项目(API)。
现在,我使用Laravel Passport对用户进行身份验证,并确保每个API调用都是授权呼叫。
现在,当我想要注销我的用户时,我向我的API发送了一个帖子请求(带有Bearer令牌)并尝试将他从API中删除(并清除会话,cookie,......)
然后在客户端上我也刷新了会话,因此不再知道令牌。现在,当我返回登录页面时,它会自动登录我的用户。 (或者我的用户刚刚登录)。
有人可以解释一下如何使用Laravel护照正确注销用户吗?
提前致谢。
答案 0 :(得分:22)
您需要从数据库表oauth_access_tokens
中删除令牌
你可以通过创建像OauthAccessToken
运行命令php artisan make:model OauthAccessToken
以创建模型。
然后在User
添加:
OauthAccessToken
模型与新创建的User.php
模型之间的关系
public function AauthAcessToken(){
return $this->hasMany('\App\OauthAccessToken');
}
,为logout创建一个新函数:
public function logoutApi()
{
if (Auth::check()) {
Auth::user()->AauthAcessToken()->delete();
}
}
在api.php路由器中,创建新路由:
Route::post('logout','UserController@logoutApi');
/api/logout
答案 1 :(得分:16)
创建退出路线:
$router->group(['middleware' => 'auth:api'], function () use ($router) {
Route::get('me/logout', 'UserController@logout');
});
在userController中创建一个注销函数(或路由中提到的)
public function logout() {
$accessToken = Auth::user()->token();
DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update([
'revoked' => true
]);
$accessToken->revoke();
return response()->json(null, 204);
}
答案 2 :(得分:11)
请确保在User
模型中已导入
use Laravel\Passport\HasApiTokens;
并且您正在使用
来使用特征HasApiTokens
use HasApiTokens
在用户类内部。 现在,您创建注销路径,并在控制器中, 做到
$user = Auth::user()->token();
$user->revoke();
return 'logged out'; // modify as per your need
这会将用户从他请求注销的当前设备中注销。如果要从他登录的所有设备中注销,请执行此操作
DB::table('oauth_access_tokens')
->where('user_id', Auth::user()->id)
->update([
'revoked' => true
]);
这将使用户从任何地方注销。当用户使用“重置密码”或“忘记密码”选项更改密码,并且您必须从任何地方注销该用户时,这确实很有帮助。
答案 3 :(得分:4)
这是我用于注销的示例代码
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
答案 4 :(得分:2)
我正在使用Laravel 6.12.0,以下功能对我有用。
public function logout(Request $request){
$accessToken = Auth::user()->token();
$token= $request->user()->tokens->find($accessToken);
$token->revoke();
$response=array();
$response['status']=1;
$response['statuscode']=200;
$response['msg']="Successfully logout";
return response()->json($response)->header('Content-Type', 'application/json');
}
答案 5 :(得分:1)
这是我的第一篇文章..我找到了一个干净的解决方案(Laravel的最新版本)
/**
* Logout api
*
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
if (Auth::check()) {
$token = Auth::user()->token();
$token->revoke();
return $this->sendResponse(null, 'User is logout');
}
else{
return $this->sendError('Unauthorised.', ['error'=>'Unauthorised'] , Response::HTTP_UNAUTHORIZED);
}
}
答案 6 :(得分:1)
下面是我发现的最简单的方法。
php artisan session:table
php artisan migrate
在您的SESSION_DRIVER=file
文件中用SESSION_DRIVER=database
替换.env
。
将用户重定向到您的前端并登录并最终获得令牌后,您可能在api/routes.php
中调用了一条路由来获取用户信息,这就是我在回发之前关闭用户后端会话的地方前端用户信息:
Route::middleware('auth:api')->get('/user', function (Request $request) {
// Close user session here
Illuminate\Support\Facades\DB::table('sessions')
->whereUserId($request->user()->id)
->delete();
return $request->user();
});
然后,要从前端“注销”(实际上是撤消令牌)用户,您只需调用另一条路由来撤消token
和refresh_token
:
Route::middleware('auth:api')->post('/logout', function (Request $request) {
// Revoke access token
// => Set oauth_access_tokens.revoked to TRUE (t)
$request->user()->token()->revoke();
// Revoke all of the token's refresh tokens
// => Set oauth_refresh_tokens.revoked to TRUE (t)
$refreshTokenRepository = app('Laravel\Passport\RefreshTokenRepository');
$refreshTokenRepository->revokeRefreshTokensByAccessTokenId($request->user()->token()->id);
return;
});
您可能希望将这两个闭包放在UserController
中。
答案 7 :(得分:0)
希望帮助某人:
if (Auth::check()) {
$request->user()->tokens->each(function ($token, $key) {
$token->delete();
});
}
祝你好运。
答案 8 :(得分:0)
我在我的项目中使用它从多个设备注销。
public function logout(Request $request, $devices = FALSE)
{
$this->logoutMultiple(\Auth::user(), $devices);
return response()->json([], 204);
}
private function logoutMultiple(\App\Models\User $user, $devices = FALSE)
{
$accessTokens = $user->tokens();
if ($devices == 'all') {
} else if ($devices == 'other') {
$accessTokens->where('id', '!=', $user->token()->id);
} else {
$accessTokens->where('id', '=', $user->token()->id);
}
$accessTokens = $accessTokens->get();
foreach ($accessTokens as $accessToken) {
$refreshToken = \DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update(['revoked' => TRUE]);
$accessToken->revoke();
}
}
答案 9 :(得分:-2)
public function logout(Request $request)
{
$request->user()->token()->revoke();
if ($request->everywhere) {
foreach ($request->user()->tokens()->whereRevoked(0)->get() as $token) {
$token->revoke();
}
}
return response()->json(['message' => 'success']);
}