Friday, 28 August 2020

Auth0 does not persist login on page refresh for email/password

I am using Auth0 as my authentication provider for a SPA using React. I have followed the Auth0 react tutorial and this more detailed tutorial from their blog.

I am currently just using just email/password authentication. And the authentication works as expected for login/logout, retrieving user info etc.

However, when I refresh the page, the isAuthenticated value from the useAuth0 always returns false. Even after isLoading resolves to true, hence I have to log in again.

This behaviour strangely does not occur on Chrome or Firefox. It fails on Brave and Safari.

I noticed in a forum post on Auth0 (another person with a similar problem) that the Auth0Provider should be doing a authorize call using prompte=none, and it is. It also returns a successful 202 shortly after the page loads (but doesn't change isAuthenticated to true). This call also sets a cookie auth0.is.authenticated=true.

authorize?client_id=VALUE&redirect_uri=VALUE&scope=openid%20profile%20email&response_type=code&response_mode=web_message&state=VALUE&nonce=VALUE&code_challenge=VALUE&code_challenge_method=S256&prompt=none&auth0Client=VALUE

Here is my route that checks the auth state. This component is wrapped in the Auth0ProviderWithHistory code as suggested in the Auth0 tutorials.

export default function Routes() {
  const { isLoading, isAuthenticated } = useAuth0()

  const getDashboard = () => {
    //determine which dashboard to return
  }

  if (isLoading) return <p>Loading...</p>

  if (isAuthenticated) {
    return (
      <Suspense fallback={<p>loading...</p>}>
        <Switch>
          <Route exact path="/">
            {getDashboard()}
          </Route>
          <Route path="/customer/:customerId">
            <Customer />
          </Route>
          <Route>
            <NotFound />
          </Route>
        </Switch>
      </Suspense>
    )
  }

  return <SignInAndRegister />
}

I have noticed when I reload the page, and call the loginWithRedirect function I am not redirected to the Universal Login page, instead there are two token calls (POST and OPTIONS). The POST call response has the following details, should I somehow capture this and saving them to reuse them to login?

access_token: "VALUE"
expires_in: 86400
id_token: "VALUE"
scope: "openid profile email"
token_type: "Bearer"

As an experiment, I downloaded the react sample on the "Quick Start" section of an application in the Auth0 dashboard to see if the behaviour was replicated there. And it was.

I had the impression that the Auth0Provider should be handling the silent authentication automagically, is this not the case?

There are not many options to use with auth0-react npm package, so I am not sure what to try next. The only available functions are:

getAccessTokenSilently: ƒ (opts)
getAccessTokenWithPopup: ƒ (opts)
getIdTokenClaims: ƒ (opts)
isAuthenticated: false
isLoading: true
loginWithPopup: ƒ (opts)
loginWithRedirect: ƒ (opts)

If this isn't possible, it looks like I might have to migrate to the @auth0/auth0-spa-js SDK.



from Auth0 does not persist login on page refresh for email/password

No comments:

Post a Comment