I’m working on a web application that needs to get refresh tokens using the PKCE flow. For reasons outside this ticket, I need to roll my own client for the Auth0 API, so I’m not using the JS SDKs.
I am attempting to follow the flow here: Add Login Using the Authorization Code Flow with PKCE
- My API has Enable Offline Access enabled
- My Application’s Grant Types include Authorization Code
- I’m successfully authorizing the user through the
/authorize
endpoint, includingoffline_access
in the scope. - I get the code after authorization, and I can successfully exchange the
code
andcode_verifier
for tokens usinggrant_type: authorization_code
But no matter what I try, I only get back access_token
and id_token
, not refresh_token
, in the /oauth/token
response payload. The response payload even includes offline_access
in its scopes
, but no refresh token is forthcoming.
What am I missing here? I’ve been banging my head against this for a day or more, and have read most of the Auth0 documentation that appears relevant.
Sample code for the /authorization
call:
// Make the URL
const params = new URLSearchParams();
params.append('response_type', 'code');
params.append('response_mode', 'query');
params.append('audience', audience);
params.append('state', state);
params.append('code_challenge', codeChallenge);
params.append('code_challenge_method', 'S256');
params.append('client_id', clientId);
params.append('redirect_uri', redirectURI);
params.append('scope', scope);
const url = `https://${domain}/authorize?${params}`;
// Redirect the current page
window.location.assign(url);
Sample code for the /oauth/token
call:
const params = new URLSearchParams();
params.append('grant_type', 'authorization_code');
params.append('audience', audience);
params.append('client_id', clientId);
params.append('code_verifier', transaction.code_verifier);
params.append('code', code);
params.append('redirect_uri', redirectURI);
const res = await request(`https://${domain}/oauth/token`, {
method: 'POST',
body: params.toString(),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
Update
I finally found the root cause in the Auth0 logs:
Type: Warning During Login
Description: The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser
Still not sure how to get around this, as I’d like to acquire a refresh token from a browser interface.