Auth Code with PKCE - Refresh Token

Per okta documentation for Auth Code with PKCE, scope=offline_access for response_type=code (/authorize endpoint) should return refresh token in addition to access token. Instead, I see an error that indicates, offline_access is an invalid scope.
Exact response: {“error”:“invalid_scope”,“error_description”:“Browser requests to the token endpoint may not include the offline_access scope.”}
Could you please let me know if I am missing something, or refresh_token is not supported with auth code flow with PKCE.
Please confirm.

Hi, you can not make a /token request with the “offline_access” scope in the frontend since it could be a security concern.

Please see the post below from http://disq.us/p/22kc559:
Yes, most authorization servers will not issue refresh tokens to JavaScript apps, because they are more risky. With public clients, the refresh token is extremely powerful, since it can be used without a secret, so many providers eliminate this risk by just not issuing refresh tokens to any kind of public client.

You can get a refresh token with the PKCE flow but the /token request would have to be from the backend. You can test this by pasting the /authorize url in the browser to retrieve a code. Then make a /token request with Postman or curl with the “offline_access” scope and it should return a refresh token.

1 Like

Thank you very much! I will try the request from Postman.

Hi, I am able to get authorization code by executing /authorize in the browser. However, this works only if the scope is “openid” (does not help with regardst to refresh token). /token from Postman with scope=offline_access does not seem to work. (invalid grant).

Hi, Just wanted to let you know that /token from Postman worked fine. I am now able to get “refresh_token”.
Thanks!

Hi, I’m trying the same thing and able to fetch a refresh token from postman. What request parameters you used to exchange this refresh token without client secret?

As you’re using PKCE, you need to ensure that the client_id and the code_verifier (used to generate the code_challenge used in the /authorize request) are included for client authentication. Your request will look something like this: https://developer.okta.com/docs/guides/implement-auth-code-pkce/exchange-code-token/

curl --request POST \
  --url https://${yourOktaDomain}/oauth2/default/v1/token \
  --header 'accept: application/json' \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'grant_type=authorization_code&client_id=0oabygpxgk9lXaMgF0h7&redirect
  _uri=yourApp%3A%2Fcallback&code=CKA9Utz2GkWlsrmnqehz&code_verifier=M25iVXpKU
  3puUjFaYWg3T1NDTDQtcW1ROUY5YXlwalNoc0hhakxifmZHag'

Hi, could someone share the exact parameters to be set? Refresh access tokens | Okta Developer has

Authorization code with PKCE requests don’t return refresh tokens if they are sent from SPAs or other browser-based apps.

The first answer to this thread has

You can get a refresh token with the PKCE flow but the /token request would have to be from the backend.

What does “backend” here mean exactly? An application configured with non-SPA?

it means web-server, not your client SPA application

1 Like

I see. Thanks! So, it works fine if the “Web” application is used…

I have one more question… In the “web” app, there is the following warming message just below the “Client secret” section.

Secret used by the client to exchange an authorization code for a token. This must be kept confidential! Do not include it in apps which cannot keep it secret, such as those running on a client.

I know this is not recommended, but what’s the exact issue of including a client secret in code that runs on a client? Wondering if it’s acceptable as long as the “Client Credentials” grant type is disabled.

I’m speculating here, but having credentials will allow evildoers to get access tokens, if they can steal refresh tokens from the client. So your access tokens then are compromised.

Do you have the answer to royb’s question: how to use the refresh token to renew access token without client secret?

you call /token with grant_type=refresh_token&refresh_token=xxxxx the rest you can grab from https://developer.okta.com/docs/reference/api/oidc/#token

@conjkq
An example /token request to get new access token using refresh token would be:

curl --location --request POST ‘https://xxx.okta.com/oauth2/default/v1/token’ \

–header ‘Accept: application/json’ \

–header ‘Content-Type: application/x-www-form-urlencoded’ \

–data-urlencode 'grant_type=refresh_token’ \

–data-urlencode ‘redirect_uri=http://localhost:8080’ \

–data-urlencode ‘client_id=0oaqfdvdr9Dvz5pUC0h7’ \

–data-urlencode 'code=xxx’ \

–data-urlencode 'code_verifier=xxx’ \

–data-urlencode ‘refresh_token=xxx’

P.S: Today, Okta does not return refresh tokens for SPA apps.

hmm,
–data-urlencode 'code=xxx’
but code is the result of authorization request. And it is good for 300 seconds.
Does it mean the authorization request needs to rerun to refresh an access token acquired by a PKCE client?

Try removing the lines for the code and code_verifier, as you would only have those during a new Authorization code flow (with PKCE), but not when simply refreshing the tokens with the refresh token.

try with scope like that: scope=openid%20offline_access

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.