# Auth Code with PKCE - Refresh Token

**URL:** <https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625>\
**Category:** OAuth/OIDC\
**Created:** [January 13, 2020, 8:09pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625 "2020-01-13T20:09:27Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![nshivade](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@nshivade](https://devforum.okta.com/u/nshivade)\
**Post date:** [January 13, 2020, 8:09pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/1 "2020-01-13T20:09:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![warren](https://avatars.discourse-cdn.com/v4/letter/w/97f17d/32.png) [@warren](https://devforum.okta.com/u/warren)\
**Post date:** [January 13, 2020, 8:46pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/2 "2020-01-13T20:46:12Z")

</div>

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:](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.

---

<div class="post-metadata">

**Author:** ![nshivade](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@nshivade](https://devforum.okta.com/u/nshivade)\
**Post date:** [January 13, 2020, 9:24pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/3 "2020-01-13T21:24:39Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![nshivade](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@nshivade](https://devforum.okta.com/u/nshivade)\
**Post date:** [January 13, 2020, 9:38pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/4 "2020-01-13T21:38:11Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![nshivade](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@nshivade](https://devforum.okta.com/u/nshivade)\
**Post date:** [January 13, 2020, 9:49pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/5 "2020-01-13T21:49:11Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![royb](https://avatars.discourse-cdn.com/v4/letter/r/aca169/32.png) [@royb](https://devforum.okta.com/u/royb)\
**Post date:** [April 14, 2020, 10:14pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/6 "2020-04-14T22:14:28Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![andrea](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/andrea/32/2172_2.png) [@andrea](https://devforum.okta.com/u/andrea)\
**Post date:** [April 20, 2020, 9:04pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/7 "2020-04-20T21:04:43Z")

</div>

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/](https://developer.okta.com/docs/guides/implement-auth-code-pkce/exchange-code-token/)

```auto
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'

```

---

<div class="post-metadata">

**Author:** ![kenjikaneda](https://avatars.discourse-cdn.com/v4/letter/k/6bbea6/32.png) [@kenjikaneda](https://devforum.okta.com/u/kenjikaneda)\
**Post date:** [October 19, 2020, 10:39pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/8 "2020-10-19T22:39:46Z")

</div>

Hi, could someone share the exact parameters to be set? [Refresh access tokens | Okta Developer](https://developer.okta.com/docs/guides/refresh-tokens/get-refresh-token/) 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?

---

<div class="post-metadata">

**Author:** ![phi1ipp](https://avatars.discourse-cdn.com/v4/letter/p/85f322/32.png) [@phi1ipp](https://devforum.okta.com/u/phi1ipp)\
**Post date:** [October 20, 2020, 12:57am UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/9 "2020-10-20T00:57:16Z")

</div>

it means web-server, not your client SPA application

---

<div class="post-metadata">

**Author:** ![kenjikaneda](https://avatars.discourse-cdn.com/v4/letter/k/6bbea6/32.png) [@kenjikaneda](https://devforum.okta.com/u/kenjikaneda)\
**Post date:** [October 20, 2020, 7:31am UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/10 "2020-10-20T07:31:46Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![phi1ipp](https://avatars.discourse-cdn.com/v4/letter/p/85f322/32.png) [@phi1ipp](https://devforum.okta.com/u/phi1ipp)\
**Post date:** [October 20, 2020, 12:45pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/11 "2020-10-20T12:45:11Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![conjkq](https://avatars.discourse-cdn.com/v4/letter/c/f9ae1b/32.png) [@conjkq](https://devforum.okta.com/u/conjkq)\
**Post date:** [November 1, 2020, 4:24pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/12 "2020-11-01T16:24:29Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![phi1ipp](https://avatars.discourse-cdn.com/v4/letter/p/85f322/32.png) [@phi1ipp](https://devforum.okta.com/u/phi1ipp)\
**Post date:** [November 2, 2020, 12:30am UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/13 "2020-11-02T00:30:02Z")

</div>

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](https://developer.okta.com/docs/reference/api/oidc/#token)

---

<div class="post-metadata">

**Author:** ![gpadma](https://avatars.discourse-cdn.com/v4/letter/g/858c86/32.png) [@gpadma](https://devforum.okta.com/u/gpadma)\
**Post date:** [November 3, 2020, 7:45pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/14 "2020-11-03T19:45:29Z")

</div>

@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](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.

---

<div class="post-metadata">

**Author:** ![gcgc](https://avatars.discourse-cdn.com/v4/letter/g/c5a1d2/32.png) [@gcgc](https://devforum.okta.com/u/gcgc)\
**Post date:** [May 19, 2021, 8:01pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/15 "2021-05-19T20:01:12Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![andrea](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/andrea/32/2172_2.png) [@andrea](https://devforum.okta.com/u/andrea)\
**Post date:** [May 25, 2021, 7:25pm UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/16 "2021-05-25T19:25:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ferlaymat](https://avatars.discourse-cdn.com/v4/letter/f/49beb7/32.png) [@ferlaymat](https://devforum.okta.com/u/ferlaymat)\
**Post date:** [August 4, 2023, 5:29am UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/17 "2023-08-04T05:29:22Z")

</div>

try with scope like that: scope=openid%20offline\_access

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/oktadev/original/1X/589c4c5f80de422d01f47cee7185a7fb8227835c.png) [@system](https://devforum.okta.com/u/system)\
**Post date:** [February 13, 2024, 12:28am UTC](https://devforum.okta.com/t/auth-code-with-pkce-refresh-token/7625/18 "2024-02-13T00:28:22Z")

</div>

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