skip to Main Content

I wrote a simple REST API with Laravel 11. I tested authentication and it looks like the token generated by Sanctum is not revoked despite that I delete the way the documentation writes.

class TokenController extends Controller
{
    public function store(Request $request){
        $fields = $request->validate([
            'email' => ['required', 'email', 'max:255'],
            'password' => ['required', 'string', 'max:255']
        ]);
        $user = User::where('email', $fields['email'])->first();
        if (!$user || !Hash::check($fields['password'], $user->password))
            return response('authentication failed', 401);

        $token = $user->createToken('the_token');
        return response([
            'plainText' => $token->plainTextToken
        ], 201);
    }

    public function destroy(Request $request){
        $request->user('sanctum')->currentAccessToken()->delete();
        return response(null, 204);
    }
}

When I test the route for destroy I got always 204 and when I dump the user id and the token I always got the same values. This should not be possible, because I use the auth:sanctum middleware for the route, so I guess I should get 401 for the second call because there is no authenticated user or at least an empty user id.

I have no idea what I am doing wrong. Maybe this is a configuration issue, but when I try to Google or GPT it all I find that other people revoked tokens the same way I do. How can I fix this?

2

Answers


  1. Chosen as BEST ANSWER

    The problem is with the test.

    I found here that Laravel can support only a single request per test: https://laravel.io/forum/revoking-sanctum-api-token-doesnt-appear-to-prevent-use

    So I had to rewrite the test to check the database content instead of requesting the server multiple times.

    public function test_deleting_token():void{
        $user = User::create($this->user1);
        $this->assertEquals($user->tokens()->get()->count(), 0);
        $token = $user->createToken('the_token')->plainTextToken;
        $this->assertEquals($user->tokens()->get()->count(), 1);
        $response = $this->withToken($token)
            ->deleteJson('/api/tokens/current');
        $response->assertStatus(204);
        $this->assertEquals($user->tokens()->get()->count(), 0);
    }
    

    off:

    I don't like to write this kind of tests, I mean it would be a lot better testing experience to write a story something like user was created, user was logged in, some posts were added, etc. Ofc. it is harder to follow these than doing stuff in isolation.


  2. I don’t think

    $request->user('sanctum') 
    

    returns anything. You might confuse it with

    auth('sanctum')->user();
    

    Try

    $request->user()->currentAccessToken()->delete();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search