Client credential flow using Axios in React - error - Browser requests to the token endpoint must use Proof Key for Code Exchange

errorCauses: []

Using axios in React app to get the token for Client Credentials flow and getting error
errorCode: “E0000021”
errorSummary: “Bad request. Accept and/or Content-Type headers likely do not match supported values.”

Here is the code:

axios.create({
baseURL: ‘XXXXX’,
headers: {
‘Access-Control-Allow-Origin’: ‘*’,
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘authorization’: 'Basic ’ + new Buffer(‘CLIENT_ID:CLIENT_SECRET’).toString(“base64”),
‘grant_type’: ‘client_credentials’,
‘scope’: ‘cim.read’
}
});

Tried other combinations passing Accept and Conent-Type as application/json;charset=UTF-8 but did not work.

Same works when called from .NET code and Postman. Not able to make it work with Axios.

Also tried a sample from this website - https://developer.okta.com/blog/2018/06/06/node-api-oauth-client-credentials?_ga=2.101749441.1715401285.1587963779-523898216.1579114747
Ended with 401 error - Browser requests to the token endpoint must use Proof Key for Code Exchange.

Appreciate any help.

Hi,

I had this issue few days ago when playing around with some oAuth flows in a .NET application.
For me the issue was the body, your request must be in form-urlencoded format aswell. Okta expects this. You specifiy in your request the content-type but are you actually sending in that format?

i was further looking into this and observed that i need to pass grant_type and scope in the body and not in header.

When i do that it gives this error {“error”:“invalid_client”,“error_description”:“Browser requests to the token endpoint must use Proof Key for Code Exchange.”}

import axios from ‘axios’;
import qs from ‘qs’;

const data = qs.stringify({
‘grant_type’: ‘client_credentials’,
‘scope’: ‘cim.read’
});

const token = btoa(‘CLIENT_ID:CLIENT_SECRET’);

axios.post(
‘URL’,
data,
{
headers : {
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Cache-control’: ‘no-cache’,
‘Authorization’: 'Basic ’ + token
}
}
).then(result => {

});

The call you are showing is for exchanging the code for an access token I assume or are you still struggling with the first call /authorize?
For Authorization you still need to be using client id/secret like you did in your first post

‘authorization’: 'Basic ’ + new Buffer(‘CLIENT_ID:CLIENT_SECRET’).toString(“base64”)

Parameters for the /token endpoint should have following parameters in body just like with your first request in www-form-urlencoded
code (which you recieved after the /authorize call)
grant_type (most likely authorization_code)
redirect_uri (this must be exactly the same as the one you have in your /authorize request)
More info - OpenID Connect & OAuth 2.0 API | Okta Developer

The PKCE error can indicate that you have configured it that way in Okta. You can either use PKCE or clientid/secret. PKCE is more secure but adds a little complexity when implementing.
Depending on the kind of app you have configured you can alter this (SPA can only do PKCE for example since there is no backend) - Screenshot - bcfaeb35cc7a754b8b6e8fecfc123f6c - Gyazo