Search code examples
reactjsjwtauth0

Access token appears to be incorrect format using auth0-react library


I am following this blog post on how to use the auth0-react library.

The post describes using the getAccessTokenSilently from the useAuth0 hook to get the access token which is used as the bearer token

  const callSecureApi = async () => {
    try {
      const token = await getAccessTokenSilently();

      const response = await fetch(`${apiUrl}/api/private-message`, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      const responseData = await response.json();

      setMessage(responseData);
    } catch (error) {
      setMessage(error.message);
    }
  };

The issue I'm having is the token doesn't appear to be a JWT token - it looks like:

RJq7USOcszn7rpyI5iDjbYAKp9pK60Ap

Does anyone know why getAccessTokenSilently isn't returning a JWT token?


Solution

  • The same task took me a while as well, the docs are neither very clear nor up-to-date there I feel. Here is what you need to do:

    1. For Auth0, you need both a Single Page Application under "Applications", and an API under "APIs"
    2. Your React App gets wrapped with something like the below. Note the audience parameter from your API, this is the crucial part, without it, I also got the same small and useless access token you got!
    <Auth0Provider
        domain={AUTH0_DOMAIN} // taken from the SPA application in Auth0
        clientId={AUTH0_CLIENT_ID} // taken from the SPA application in Auth0
        authorizationParams={{
            audience={AUTH0_AUDIENCE} // taken from your API in Auth0
            redirectUri={window.location.origin}
        }}
        useRefreshTokens={true}
        cacheLocation={"localstorage"}
    >
    
    1. Wherever you want to call your Backend (e.g. Spring Boot), you add the following to the component:
    const {user, getAccessTokenSilently} = useAuth0();
    ...
    // this will now be a JWT token, BUT ONLY if you specified the API audience in the Auth0Provider
    // looks something like this:
    /* eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlFqZEVNMEU1TnpWRE0wTkRSRVEzUkVFMFFVSkJOamMwUmtGRE1qZzNPVGxCTURNMk56UTJSZyJ9.eyJpc3MiOiJodHRwczovL3JhcGlkbWluZXIuYXV0aDAuY29tLyIsGnN1YiI6ImF1dGgwfDUzNDc5YzMwNmU5Yjc4YTU3MzAwMDVjNSIsImF1ZCI6WyJodHRwczovL2VuZ2luZWVyaW5nLXRvb2xzLnJhcGlkbWluZXIuY29tL2FwaSIsImh0dHBzOi8vcmFwaWRtaW5lci5hdXRoMC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNTk2ODM2MDMyLCJleHAiOjE1OTY5MjI0MzIsImF6cCI6IllldWhoS29JV1lTV2FYUmExNU1sNTFMZUExYkp4bjVlIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.zI74HHd1pCzz-xBQEDDKby9z_Ue9_AIz-r05_my1wvLQ0U94u9WrwWmSxd9BQ-2XOHKa1KgnaaxsX2aiSHil7a4YjMnrYo9f0jgMmlxcllqZJgeb0AhLQNfYQEr6nAKP_8PgN0D7QFjIxiFTpDndTcD_2nG9DEsxbraT7dDy0pf1KTGmhQnNyBuyReAEUFhlxd1LAd63ED14nCPmEehl5rLNUwClTRFQ5q4ERLjM8cX0GLLy5F-I7UjpDOBnrL_qMqfuHyuChxs-k0fHhhEfV8xE2nEV00cXcAp3zvpJ_Ox9U0OBaVUbf1vi9v1Wl6jaMZpgqRZ1bZcfDXWjoEBVlQ */
    const accessToken = await getAccessTokenSilently();
    
    1. Now you can pass the accessToken along via Authorization header:
    headers: {
        "Authorization": `bearer ${accessToken}`
    }
    
    1. Your BE can now validate the regular JWT token.