I am using AWS Cognito-hosted UI for my signup and login. There is no app client secret defined.
I am trying to make an API call from the browser javascript code to the /oauth2/token endpoint in order to exchange autohorization_token with an ID token.
The problem is, when I make the call through Postman, Insomnia it works fine. However, when I make the same call through javascript from the browser it fails with the 400 response type and I can't get much about the reason.
This is the Insomnia call which is a success;
However, when I make the same call via javascript it fails. I have used both fetch and XMLHttpRequest and the same result.
const XHR = new XMLHttpRequest();
let urlEncodedData = "",
urlEncodedDataPairs = [],
name;
urlEncodedDataPairs.push( encodeURIComponent( 'grant_type' ) + '=' + encodeURIComponent( 'authorization_code' ) );
urlEncodedDataPairs.push( encodeURIComponent( 'code' ) + '=' + encodeURIComponent( code ) );
urlEncodedDataPairs.push( encodeURIComponent( 'client_id' ) + '=' + encodeURIComponent( 'xxxxx' ) );
urlEncodedDataPairs.push( encodeURIComponent( 'redirect_url' ) + '=' + encodeURIComponent( 'https://www.xxx.me/xxx' ) );
XHR.addEventListener( 'load', function(event) {
alert( 'Yeah! Data sent and response loaded.' );
} );
// Define what happens in case of error
XHR.addEventListener( 'error', function(event) {
alert( 'Oops! Something went wrong.' );
});
// Set up our request
XHR.open( 'POST', 'https://xxx.auth.us-west-2.amazoncognito.com/oauth2/token' );
// Add the required HTTP header for form data POST requests
XHR.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
// Finally, send our data.
XHR.send( urlEncodedData );
This is the response I am getting:
I have tried the same request with fetch and the result is the same.
let tokenRequest = new Request(tokenURL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Origin' : 'https://www.xxx.me'
},
body: new URLSearchParams({
'grant_type': 'authorization_code',
'code': code,
'client_id': 'xxx',
'redirect_url': 'https://www.xxx.me/xxx'
}).toString()
});
let response = await fetch(tokenRequest);
let data = await response.json();
One thing I have realized when I check the browser developer tool for other POST calls made to auth endpoints with content type=application/x-www-form-urlencoded, it shows query params added to URL like shown below, however, for my call, params are not encoded as part of URL. I am not sure if the problem might be related to this.
Any idea how I can make this call with client-side javascript?