Auth0 Home Blog Docs

Persisting Login Between Refreshes

#1

Hey all, I’m using the implicit grant login flow and I am very confused.

The https://auth0.com/docs/flows/concepts/single-page-login-flow does not have any information on what to do with access tokens if the page refreshes.

Obviously if you refresh, making the user go to login again is a terrible user experience.

And then https://auth0.com/docs/security/store-tokens says not to store access tokens in local storage. So if not there, where do I store it?

It recommends storing it on my API, but that also does not make any sense. I could create a Bearer Token or HAWK64 and send that back to the client. But then I run into the same thing, if I refresh the page, that token is gone, and if I store it, we’re back to square one, a cross domain scripting attack could take the token and masquerade as the user.

1 Like
#2

Hello @jiaccarino,

The references below might be what you are looking for.

#3

I should mention specifically I am talking about a page refresh, not a token refresh. (I don’t actually want to ditch the access token, I am trying to preserve a session on my API)

I’ve realized since posting this I need to use a session identifier (created by my API) on a SameSite cookie, and store the access token on the API server, yes?

#4

For SPAs, you still need to use checkSession() to remain logged in. Have a look at the following blog post which provides a detailed example of a React app. Scroll down to the “Keeping Users Signed In after a Refresh” section, about 3/4s of the way down the page.

#5

Oh interesting. So I should use that to get user details instead of calling my API to retrieve a cached session?

Additionally, checkSession doesn’t work for me. It says: “responseType is required”

#6

I’ve also made a flowchart to help outline my understanding. Is this more correct?

#7

Ever figure this out? The tokens have to be persisted on the client somehow with implicit flow and auth0 doesn’t want you using local storage. I don’t really see another way unless you go with authorization flow and use httponly cookies from the server.

#8

Yes’m! Just recall the API.

auth0.checkSession(
        {
          scope: "openid profile email"
        },
        function (err, authResult) {
          // err if automatic parseHash fails
          if (err !== undefined && err) {
            console.error(err);
            return;
          }

          resolve(authResult);
        });

Calling this will fetch a new idToken and access token if the user has already signed on once. I pass both the idtoken and access token up to my API every time I call it like Bearer <Access_Token> <ID_Token>.

#9

Hmmm, I’m doing that as well, but I thought that the renew tokens just helped with expired tokens. My problem is on page reload–everything in-memory is blown away so if there isn’t anything in browser storage or a cookie, I have to log in again. How are you persisting your token info on a page reload?

Thanks!

#10

I don’t, I pull the tokens from authResult. :slight_smile:

authResult.idToken and authResult.accessToken.

It doesn’t ask me to log in again.

this.auth0 = new auth0.WebAuth({
  domain:       AUTH0_DOMAIN,
  clientID:     AUTH0_CLIENT_ID,
  audience:     AUTH0_AUDIENCE,
  redirectUri: SITE_URL + '/auth/confirm',
  responseType: 'id_token token',
});

That’s how I have my client set up. AuthResult will always query Auth0 for new tokens if the session isn’t expired on their end. You don’t have to store anything.

#11

Thanks a lot @jiaccarino for sharing all that knowledge with the rest of community!

1 Like
#12

So I’m have a similar issue with persisting logins in a React SPA. However, calling checkSession does nothing. No errors, nothing. I can console log inside of the callback and it never gets called. I’ve pulled the Auth class directly from the examples. Login works just fine, but when I try to renewSession (which calls checkSession), nothing happens.