auth0 / node-auth0

Node.js client library for the Auth0 platform.
MIT License
633 stars 309 forks source link

Refresh Token Grant Access Token is Missing Payload #983

Open davidwarshaw opened 8 months ago

davidwarshaw commented 8 months ago

Checklist

Description

I’m using the latest version of auth0-node (4.2.0) to do a refresh grant exactly as shown in the example:

import { AuthenticationClient } from 'auth0';

const auth = new AuthenticationClient({
  domain: '{YOUR_TENANT_AND REGION}.auth0.com',
  clientId: '{YOUR_CLIENT_ID}',
  clientSecret: '{YOUR_CLIENT_SECRET}',
});

// Get a new access token
const {
  data: { access_token },
} = await auth.oauth.refreshTokenGrant({
  refresh_token: refreshToken,
});

I’ve populated domain with the tenant and region subdomain as shown in the example. The access token returned is missing the payload:

"access_token": "[...]29tLyJ9..JdBYlv[...]", // <- token is missing payload:

I posted this issue to the Auth0 community board: https://community.auth0.com/t/auth0-node-refresh-grant-missing-payload/125305

Reproduction

  1. Create the client as in the example:
    const auth = new AuthenticationClient({
    domain: '{YOUR_TENANT_AND REGION}.auth0.com',
    clientId: '{YOUR_CLIENT_ID}',
    clientSecret: '{YOUR_CLIENT_SECRET}',
    });
  2. Make a refresh token grant using the client method:
    // Get a new access token
    const data = await auth.oauth.refreshTokenGrant({ refresh_token: refreshToken });
  3. The access token is missing the payload:
    [...]
    "access_token": "[...]29tLyJ9..JdBYlv[...]", // <- token is missing payload:
    [...]

Additional context

The node grant request looks like this:

{
  path: '/oauth/token',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: URLSearchParams {
    'client_id' => MY_CLIENT_ID,
    'refresh_token' => MY_REFRESH_TOKEN,
    'client_secret' => MY_CLIENT_SECRET,
    'grant_type' => 'refresh_token' }
}

By default, the request is not sent with the audience, which could result in the access token payload being missing. I tried passing the audience in the grant payload:

const data = await auth0.oauth.refreshTokenGrant({
      audience: MY_AUDIENCE,
      refresh_token,
    });

which resulted in the audience being sent in the request:

{
  path: '/oauth/token',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: URLSearchParams {
    'client_id' => MY_CLIENT_ID,
    'audience' => MY_AUDIENCE,
    'refresh_token' => MY_REFRESH_TOKEN,
    'client_secret' => MY_CLIENT_SECRET,
    'grant_type' => 'refresh_token' }
}

however, the access token was still missing the payload.

The equivalent curl command also returned an access token with missing payload.

❯ curl --request POST   --url https://MY_DOMAIN/oauth/token   --header 'content-type: application/json'   --data '{"client_id":"MY_CLIENT_ID","client_secret":"MY_CLIENT_SECRET","audience":"MY_AUDIENCE","grant_type":"refresh_token", "refresh_token": "MY_REFRESH_TOKEN"}'

Password and client credentials grants work without issue.

node-auth0 version

4.2.0

Node.js version

18.16.0

davidwarshaw commented 8 months ago

Re the community forum post here: https://community.auth0.com/t/auth0-node-refresh-grant-missing-payload/125305

This is expected behavior. In order for a refresh token grant to return a JWT access token, instead of an opaque token (token without a payload), the original offline_access token grant must have included an audience. This is not clear in the documentation. I opened PR: https://github.com/auth0/node-auth0/pull/984 to clarify.

frederikprijck commented 8 months ago

Thanks for the PR. I left a comment on the PR.