Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setToken (and possibly setRequest) return the previously logged in user #264

Open
carvefx opened this issue Aug 30, 2024 · 2 comments
Open
Labels
bug Something isn't working

Comments

@carvefx
Copy link

carvefx commented Aug 30, 2024

setToken (and possibly setRequest) return the previously logged in user

JwtGuard::setToken and JwtGuard::setRequest, if used in a long-running environment (a la octane etc, or a websockets server in my case) will not reset the user, but simply overwrite the token.

This leads to a behaviour where if there exists a cached user, and you reset the token, and call

$user = auth()->setToken('eyJhb...')->user();

# taken from official docs https://laravel-jwt-auth.readthedocs.io/en/latest/auth-guard/#set-the-token-explicitly

you will get the cached user, instead of the user represented by the new token.

Your environment:

Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 10.x
Package version 2.7.§
PHP version 8.2

Steps to reproduce

In a loop, log in a user via setting the token, and then do it again with a new token, the user() method will return the original user.

Expected behaviour

setting a token should invalidate the user cache

Actual behaviour

setting a token returns the "previous" / "cached" user

@carvefx carvefx added the bug Something isn't working label Aug 30, 2024
@mahdimirhendi
Copy link

Description

Yes I tested and it's serious problem. Here’s a test that demonstrates the problem:

test('user token returns correct user profile', function () {
    // Create and authenticate the first user
    $userOne = User::factory()->create()->refresh();
    $tokenOne = auth('User')->tokenById($userOne->id);
    $responseOne = $this->getJson(route('users.profile'), [
        'Authorization' => "Bearer {$tokenOne}",
    ]);

    // Create and authenticate the second user
    $userTwo = User::factory()->create()->refresh();
    $tokenTwo = auth('User')->tokenById($userTwo->id);
    $responseTwo = $this->getJson(route('users.profile'), [
        'Authorization' => "Bearer {$tokenTwo}",
    ]);

    // Extract user details from the responses
    $userOneDetails = [
        'name' => $userOne->name,
        'token' => $tokenOne,
        'profile' => $responseOne->json(),
    ];

    $userTwoDetails = [
        'name' => $userTwo->name,
        'token' => $tokenTwo,
        'profile' => $responseTwo->json(),
    ];

    // Assert that profiles of different users are not equal
    $this->assertNotEquals(
        $userOneDetails['profile'],
        $userTwoDetails['profile'],
        'The profiles for different users should not be equal.'
    );
});

@Messhias
Copy link
Collaborator

The JWT use context to generate tokens, it's not a database token based. So if the state is the same, user will be the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants