5

In my unit test, I have a user for whom I generate a token:

$tokenString = $this->user->createToken('PHPunit', ['example'])->accessToken;

How can I afterward delete this user's token?

Mister Verleg
  • 4,053
  • 5
  • 43
  • 68

6 Answers6

5

This is what I do when a user logged out.

public function logout() {
    Auth::user()->tokens->each(function($token, $key) {
        $token->delete();
    });

    return response()->json('Successfully logged out');
}

This code will remove each token the user generated.

Japs
  • 977
  • 2
  • 10
  • 19
3

I think something like this can revoke the token:

$this->user->token()->revoke()

Based on this link.

Rouhollah Mazarei
  • 3,969
  • 1
  • 14
  • 20
3

Laravel Sanctum documentation stated 3 different ways to revoke tokens. you can find it here.
but for most cases we just revoke all user's tokens via:

// Revoke all tokens...
auth()->user()->tokens()->delete();

note: for some reason intelephense gives an error saying tokens() method not defined but the code works fine. Hirotaka Miyata found a workaround here.
so the over all logout method can be something like this:

public function logout()
{
    //the comment below just to ignore intelephense(1013) annoying error.
    /** @var \App\Models\User $user **/
    $user = Auth::user();
    $user->tokens()->delete();

    return [
        'message' => 'logged out'
    ];
}
CSEMN
  • 31
  • 3
2

the best working solution is this

public function logout(LogoutRequest $request): \Illuminate\Http\JsonResponse
    {
        if(!$user = User::where('uuid',$request->uuid)->first())
            return $this->failResponse("User not found!", 401);

        try {
            $this->revokeTokens($user->tokens);

            return $this->successResponse([

            ], HTTP_OK, 'Successfully Logout');

        }catch (\Exception $exception) {
            ExceptionLog::exception($exception);

            return $this->failResponse($exception->getMessage());
        }

    }

    public function revokeTokens($userTokens)
    {
        foreach($userTokens as $token) {
            $token->revoke();
        }
    }
1
public function __invoke(Request $request)
{
    $request->user()
        ->tokens
        ->each(function ($token, $key) {
            $this->revokeAccessAndRefreshTokens($token->id);
        });

    return response()->json('Logged out successfully', 200);
}

protected function revokeAccessAndRefreshTokens($tokenId) {
    $tokenRepository = app('Laravel\Passport\TokenRepository');
    $refreshTokenRepository = app('Laravel\Passport\RefreshTokenRepository');

    $tokenRepository->revokeAccessToken($tokenId);
    $refreshTokenRepository->revokeRefreshTokensByAccessTokenId($tokenId);
}
  • 1
    Note that this comment is referenced at https://laracasts.com/discuss/channels/laravel/laravel-passport-how-to-revoke-and-delete-refresh-token?reply=622432 – peter.babic May 22 '23 at 21:14
1

The problem with these answers is, you are deleting all the tokens if the same user has 2 or more sessions opened in different browsers/devices.

I think it's better to use

$request->user()->currentAccessToken()->delete();

So, this is the code I'm using in my API:

    public function logout()
    {
         
        auth()->user()->currentAccessToken()->delete();
    
        return ['message' => 'Desconexión exitosa'];
    
    }

It's possible also to delete an specific token

$user->tokens()->where('id', $tokenId)->delete();

Documentation here: https://laravel.com/docs/10.x/sanctum#revoking-tokens

Alex Angelico
  • 3,710
  • 8
  • 31
  • 49