Session Token does not expire on log out

We were able to find that the Session Token does not expire on log out. This is highly risky as anyone who gets access to the token can reuse it to access the website even if the user has logged out.
We use SPA + API. Our back-end implemented according to recommendation: Node.js API Implementation (SPAs + API).

Is there any solution to resolve this on auth0 side? Or we need to implement kinda custom application session to track when user is login/logout?

Thank you.

Hi @alex37,

Welcome to the Auth0 Community!

Could you please clarify if you used the /v2/logout endpoint to log your users out?

If not, calling the /v2/logout endpoint will log the users out and prevent them from logging in.

This is described in more detail in our Logout documentation.

Please let me know how this goes for you.

Thanks,
Rueben

Hi.
Yes, we use /v2/logout when we log out user from client (SPA).
On client logout works correct.
But if after logout on client we try to fetch data from server (by using http client with credentials from client before log out) - server send response with data (same as when user is logged in).

Hi @alex37,

Thank you for your response.

That’s great! Glad it works.

Could you please share the code you used to fetch the data and the response? Make sure to hide any sensitive data and use dummy values.

Thanks,
Rueben

That is our server middleware, that check authentication:
auth.js

// Set up Auth0 configuration
const authConfig = {
  domain: 'auth0_domain',
  audience: 'auth0_audience',
};

// Define middleware that validates incoming bearer tokens
// using JWKS from YOUR_DOMAIN
module.exports = jwt({
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://${authConfig.domain}/.well-known/jwks.json`,
  }),

  audience: authConfig.audience,
  issuer: `https://${authConfig.domain}/`,
  algorithm: ['RS256'],
})

This validation passed successfully and joined auth0 user data to request, like this:

req.user: {
  iss: 'https://some-project.auth0.com/',
  sub: 'auth0|someId',
  aud: [
    'https://some-project.com',
    'https://some-project.auth0.com/userinfo'
  ],
  iat: 1673300522,
  exp: 1673386922,
  azp: 'string',
  scope: 'scopes'
}

We expect, that JWT check should not pass, because user already logged out on client.

Hi @alex37,

Thank you for your reply.

It looks like you are trying to verify that the Access Token is a JWT and read the payload data. This is equivalent to taking the Access Token and pasting that into jwt.io to see its contents.

In other words, you are decoding an invalidated (old) access token with the same payload data. If you try to use it, you won’t have access to protected resources. You should expect a 401 Unauthorized error when you use this access token.

I hope this clarifies your concerns!

May I help you with anything else?

Thanks,
Rueben

Thank you for the answer.

So as I understand our implementation is correct and JWT should return 401 Unauthorized error when we decoding invalidated (old) access token?
If yes, then it does not work as expected in my case. Even after user log out, if I put old access_token to JWT - it decodes it successfully and return payload.
I also tried to use old access_token in userInfo request, and it works:

GET https://YOUR_DOMAIN/userinfo
Authorization: 'Bearer {ACCESS_TOKEN_OLD}'

Do you have any ideas why? (I have an assumption that using /v2/logout does not invalidate the access_token and it’s still work until expiration date is relevant?)

Hi @alex37,

Thank you for your reply.

Please be careful that there is a difference between validating and using an access token.

See the differences explained in our Validate Access Tokens and Use Access Tokens documentation.

The code snippet you shared is for validating the access token. For example, you can force the validation to fail by not passing an audience parameter to return an opaque access token. This would cause the JWT check to fail and not allow it to be used against the API.

Next, when using an access token, you must use it to access an API’s protected resource. So for example, if an audience parameter was set and the user has logged out by calling /v2/logout then using that access token with that API will fail. Similarly, if the access token expires on its own, it cannot be used.

I recommend reviewing our Logout documentation again if you have any doubts about the /v2/logout endpoint.

Please let me know if I can help answer any further questions.

Thanks,
Rueben

Thank you for the explanation.
I came to conclusion, that we missed Application Session Layer in our back-end.
From instruction
Application Session Layer: The first layer is the session inside your application. Though your application uses Auth0 to authenticate users, you'll still need to track that the user has logged in to your application.
If you have some example of it’s implementation, please share.

Thanks for the help.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.