Get Auth0 access_token from existing id_token
<p>I'm using <a href="http://auth0.com" rel="nofollow noreferrer">auth0</a> to authenticate my logins to my Single Page App (built on React). I'm mostly using the base API calls (listed <a href="https://auth0.com/docs/api/authentication" rel="nofollow noreferrer">here</a>).</p>

<p>The process I'm using is:</p>

<p>get username/email and password when the user enters them on my app's login page
Send a POST request to <code>/oauth/ro</code> with those values - here is that code:</p>

<pre><code>export const login = (params, err) =&gt; {
  if (err) return err
  const {email, password} = params
  const {AUTH0_CLIENT_ID, AUTH0_DOMAIN} = process.env
  return fetch(`${AUTH0_DOMAIN}/oauth/ro`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      'client_id': AUTH0_CLIENT_ID,
      'username': email,
      'password': password,
      'connection': 'Username-Password-Authentication',
      'grant_type': 'password',
      'scope': 'openid',
      'device': '',
      'id_token': ''
    })
  })
  .then(response =&gt; response.json())
  .then(json =&gt; {
    const {id_token, access_token} = json
    setCookieValue('id_token', id_token) // utility function I wrote
    return getProfile(access_token)
      .then(data =&gt; {
        const {user_id, email: emailAddress, picture, name} = data
        return {id_token, user_id, emailAddress, picture, name}
      })
  })
  .catch(error =&gt; console.log(`ERROR: ${error}`))
}
</code></pre>

<p>This is all sent through Redux and the user is logged in (assuming the username/password was correct).</p>

<p>However, I'm trying to figure out how to persist the login when refreshing the page/coming back to the app. I'm saving the <code>id_token</code> (which is a <a href="http://jwt.io" rel="nofollow noreferrer">JWT</a>) in the browser's cookies and can fetch this when the app renders server-side. I can decode the JWT and get the payload (<code>sub</code> is the user ID from auth0). However, to get the profile data I need the <code>access_token</code> which Auth0 provides when using the <code>/oauth/ro</code> POST request. Obviously, if the JWT token has expired then it will just reject it and keep the user logged out.</p>

<p>Here is my code to decode the JWT (happens on app render):</p>

<pre><code>const ID_TOKEN = req.cookies.id_token || false
if (ID_TOKEN) {
  verifyJwt(ID_TOKEN, (err, decoded) =&gt; {
    if (err) { console.log(`JWT Verification error: ${err}`) }
    else {
      const {sub} = decoded
      getProfile(sub).then(data =&gt; store.dispatch(fetchUserDetails(data))) // fails as `sub` (the user id) is not the `access_token` which it requires
    }
  })
}
</code></pre>

<p>I have tried using the <code>/oauth/ro</code> call again, but this time specifying <code>"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"</code> and using the <code>id_token</code> retrieved from the cookies, and specifying a <code>device</code>. However, when I do this call, I get this error from Auth0:</p>

<pre><code>{
  "error": "invalid_request",
  "error_description": "there is not an associated public key for specified client_id/user_id/device"
}
</code></pre>

<p>So my question is, what API call do I need to make to get the <code>access_token</code> from the <code>id_token</code> JWT?</p>

<p>Also, as a bonus - when I do the POST request to login, the <code>password</code> is being transfered over plaintext. How would I encrypt this when sending to auth0 so they can decrypt it back? I assume it involves using the <code>client_secret</code> which auth0 provide but I'm not sure how to go about doing that.</p>