I am getting a CORS error everytime i try to exchange the code from the auth url for the access token , how to fix it ? I am working on a NEXT-JS project

What’s the error you’re getting back from Asana? Or is it “Token exchange failed”

From asana i am getting back this CORS issue , the error token exchange failed is something I have written for catching the error

const axios = require("axios").default;
const qs = require("qs"); 
const headers = {
   Accept: 'application/json',
  'Content-Type': 'application/x-www-form-urlencoded'

const tokenExchange = async (code: string) => {

  const clientId = "XXXXXXXX";
  const clientSecret = "XXXXXXXXX";
  const redirectUri = "http://localhost:3000/applogin/asana";
  const grantType = "authorization_code";

  const requestBody = {
    grant_type: grantType,
    client_id: clientId,
    client_secret: clientSecret,
    redirect_uri: redirectUri,
    code: code,

  const url = 'https://app.asana.com/-/oauth_token';
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: headers,
      body : qs.stringify(requestBody)
    const responseData = await response.json();
    console.log('Access token:', responseData.access_token);
    return responseData.access_token;
  } catch (error) {
    console.error({ error });
    throw new Error('Token exchange failed');
export default tokenExchange;

I am able to generate the correct payload but fail to exchange the code for the access token , not sure what I am doing wrong

What happens if you call this directly on your browser? So:


Does that work?

Getting No route found error

did you replace with your actual params?

yes yes obviously

Hmm, that’s odd sorry can’t help much from here because even using the example URL you get some sort of error, I feel like the params you’re passing in are not being formatted correctly – I’d try printing out your requestBody to see if it’s what you expect

example URL: Log in - Asana

You can’t call that url from client-side in browser.

That’s because you must provide your secret key, that should be kept, secret :slight_smile: !
So, your browser need to call your server that will do the oauth_token call for you.
It’s the same to get a new token from the refresh_token.
API tokens expires in less than 60 minutes.

Asana did not provide the required headers to allow cross-origin client-side calls, and that’s ok that they didn’t for that reason.


Okay , but the code i provided is a server side code , i am extracting the code from redirect authorization url and then passing that code to make this server side call for exchange of access token basically doing a POST request , it worked on Postman but on browser got this CORS error

So it’s not server side