如何使用laravel Passport从API注销用户

时间:2017-04-10 08:32:35

标签: laravel laravel-passport

我目前正在使用2个项目。 1个前端(使用laravel后端与API通信)和另一个laravel项目(API)。

现在,我使用Laravel Passport对用户进行身份验证,并确保每个API调用都是授权呼叫。

现在,当我想要注销我的用户时,我向我的API发送了一个帖子请求(带有Bearer令牌)并尝试将他从API中删除(并清除会话,cookie,......)

然后在客户端上我也刷新了会话,因此不再知道令牌。现在,当我返回登录页面时,它会自动登录我的用户。 (或者我的用户刚刚登录)。

有人可以解释一下如何使用Laravel护照正确注销用户吗?

提前致谢。

10 个答案:

答案 0 :(得分:22)

您需要从数据库表oauth_access_tokens中删除令牌 你可以通过创建像OauthAccessToken

这样的新模型来做到这一点
  1. 运行命令php artisan make:model OauthAccessToken以创建模型。

  2. 然后在User添加:

    中创建OauthAccessToken模型与新创建的User.php模型之间的关系
    public function AauthAcessToken(){
        return $this->hasMany('\App\OauthAccessToken');
    }
    
  3. 在UserController.php中
  4. ,为logout创建一个新函数:

    public function logoutApi()
    { 
        if (Auth::check()) {
           Auth::user()->AauthAcessToken()->delete();
        }
    }
    
  5. 在api.php路由器中,创建新路由:

     Route::post('logout','UserController@logoutApi');
    
  6. 现在,您可以通过调用发布到网址/api/logout
  7. 来注销

答案 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)

下面是我发现的最简单的方法。

1。使用数据库会话代替文件会话

Official documention

php artisan session:table
php artisan migrate

在您的SESSION_DRIVER=file文件中用SESSION_DRIVER=database替换.env

2。登录后立即删除用户会话

将用户重定向到您的前端并登录并最终获得令牌后,您可能在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();
});

3。退出时撤回令牌

然后,要从前端“注销”(实际上是撤消令牌)用户,您只需调用另一条路由来撤消tokenrefresh_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']);
}