Skip to content

Library can return tokens for different users depending on the audience in the request if users log in without first calling logout #1433

@mogzol

Description

@mogzol

Checklist

Description

I am not sure if this is actually an issue, but it seems like very strange behaviour to me. If this behaviour is intended then this can be closed.

The issue is that when using refresh tokens, if logout is not called before logging in, it is possible to get into a state where depending on what audience you use in the getTokenSilently request, the token returned will be for completely different users. There is no indication that this is happening, and the ID token in the cache will change to be whatever user the most recently updated token was for. Additionally, it's not even possible to check what user the returned access token is for without decoding it, and this library doesn't provide any way to do that.

The reason this happens is that logging in only updates the default token in the cache, and does not update or clear any other cached tokens.

This seems especially likely to happen when using MRRT, since there are likely to be multiple tokens in the cache for different audiences. But it can also happen without MRRT if useRefreshTokensFallback is enabled.

Reproduction

  1. Create a new Auth0Client instance with useRefreshTokens: true and either useMrrt or useRefreshTokensFallback set to true, to allow us to request tokens for multiple audiences.
  2. Log in using either loginWithPopup or loginWithRedirect
  3. Request a token for a new audience:
    auth0Client.getTokenSilently({ authorizationParams: { audience: "https://second-api.example.com" }})
  4. Without clearing the cache (so without calling logout), log in again with loginWithPopup or loginWithRedirect as a different user.
  5. Request the token for the second audience again:
    auth0Client.getTokenSilently({ authorizationParams: { audience: "https://second-api.example.com" }})
  6. Observe that the returned token is a token for the first user, and not the newly logged in user. If you instead call auth0Client.getTokenSilently() without any parameters to get the default token, then that token is for the newly logged in user.
  7. Also observe that even if you use { cacheMode: "off" } to force a new token to be retrieved, it will still be for the old user, since the refresh token is stored along with the cache entry.
  8. If you call getUser, observe that the user changes depending on which token most recently updated.

Additional context

Like I mentioned, this issue is caused by the fact that logging in only updates the default cache entry, and not any other cached tokens.

You could argue this behaviour is intentional since logout was never called, but I think it is very strange to allow this to happen at all, especially since there's no easy way to detect it as we can't easily see what user an access token is for. It seems like it could only lead to problems, I can't imagine wanting this behaviour.

The simplest fix would be to just clear the cache whenever a new user logs in, that is the behaviour I would expect.

auth0-spa-js version

2.5.0

Which framework are you using (React, Angular, Vue...)?

n/a

Framework version

n/a

Which browsers have you tested in?

Chrome, Firefox, Safari

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis points to a verified bug in the code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions