SPA+API architecture with PKCE and refresh token

I’am new in auth0. I am having some issues to setup my architecture using auth0.

I am using:

  • SPA - react app with auth0 hooks
  • Golang server API + mysql database
  • Universal login with lock

I defined my authentication config as following:

  • PKCE with Log In Session Management
    • Inactivity timeout == 1 minute, Require log in after == 2 minutes
  • Application Tokens
    • ID Token Expiration == 36000, token rotation enabled, Refresh Token Lifetime == 2592000 , Refresh Token Reuse Interval == 5
  • API token settings
    • Token Expiration == 900, Token Expiration For Browser Flows = 900

First doubt :slight_smile:
I know that the refresh token should be long and access token should be shorter, and I presume that the session should be shorter in this flow. Is it right?

The session is not preserved after refresh or across pages, I think that I should save the refresh token to request a new access token in this cases, right? If yes, How do I implement it?

About persisting refresh tokens on local storage, I found the cache argument for Auth0Provider (cacheLocation=“localstorage”), but it saves other sensitive data as well. Knowing that, should I code this save mechanism? Is there an option to pass it in getAccessTokenSilently ( from useAuth0) call?

I appreciate any help with this setup :slight_smile:

1 Like

Hey @dlohmann0! Welcome to the community! Apologies for the delayed response.

These are great questions. Session expiration is somewhat tricky, though, as there are many layers (app session, IDP session, 3rd party IDP session, etc). Usually it is simple in case of one app, but quickly becomes complex in case of multiple apps with different requirements. In those cases sometimes it may be ok to have unusual expiration times - like token expiration can be longer than the session. However most of the time such situation means that there wasn’t enough analysis and the customer should consider step-up/MFA instead. Long story short, normally, you’d have a shorter access token, longer refresh token, and a shorter session.

For a single page app, you could persist logged in state in different ways depending on the SDK you’re using. I presume you’re using auth0-spa-js, in which case there’s a method you’d provide as a ‘value’ to your Auth0.Context wrapper: getTokenSilently: (...p) => auth0Client.getTokenSilently(...p). Here’s an example app with this implemented (try deploying it, logging in and refreshing the page). It’s unofficial, but it’s based on Auth0 React SPA example and features persistence :slight_smile:

Now, when it comes to storing tokens in localStorage, there’s a theoretical risk of exposing this data in case of an XSS attack. With this being said, XSS attack is basically a “game over” anyway. So we suggest to put all efforts possible into preventing this kind of attack. To minimize damage in case of XSS attack, you could try minimizing sensitive data you store in a token and tweak it’s expiration time.

I hope this answers your questions. Please let me know if you need any details or clarifications regarding this.

Hi @art.rosnovsky, I am very thankful for your answer.
About tokens expiration, it’s completely clear the flow, your explanation helped me a lot :slight_smile:

The code is great solution to pass parameters, I will use it as idea (solved the problem of passing params).

About the refresh token,
For me is not so clear how to do it, I was studding the auth0-spa.js code, more precisely in Auth0Client.ts

'_getTokenUsingRefreshToken(getTokenOptions) {…} ’ I think if pass the refresh token as parameter it will ignore by cache params and fallback to an iframe. Maybe I need another workaround for that, like call the auth0 endpoints with refresh token (stored by myself ) every time that user refresh the page.

lines: 811-816
// If you don’t have a refresh token in memory
// and you don’t have a refresh token in web worker memory
// fallback to an iframe.
if ((!cache || !cache.refresh_token) && !this.worker) {
return await this._getTokenFromIFrame(options);

I need more time to test it and we are running to finish the project. I am considering in remove refresh token for while, at least in version 1. Just using PKCE flow. (I will try to do the refresh token asap and reply here)

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