SirGolem
SirGolem

Reputation: 147

'unsupported_grant_type' when trying to get an access token from Discord API

So I am trying to implement Discord login to my website, but when trying to exchange the code for an access token from https://discord.com/api/oauth2/token I just get { error: 'unsupported_grant_type' }.

My code:

        const tokenResponseData = await request('https://discord.com/api/oauth2/token', {
            method: 'POST',
            data: JSON.stringify({
                client_id: config.clientId,
                client_secret: config.clientSecret,
                code: code,
                grant_type: 'authorization_code',
                redirect_uri: `http://localhost:3000/api/auth`,
                scope: 'identify',
            }),
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        });

Been struggling with this for a while now, so any help would be great!

Upvotes: 1

Views: 2644

Answers (2)

SirGolem
SirGolem

Reputation: 147

Turns out I was doing it all wrong. I needed to have the request parameters formatted like URL queries and sent as a string in the body of the POST request.

const tokenResponseData = await fetch(
  `https://discord.com/api/oauth2/token`,
  {
    method: 'POST',
    body: `client_id=${encodeURIComponent(`${config.clientId}`)}&client_secret=${encodeURIComponent(`${config.clientSecret}`)}&grant_type=authorization_code&code=${code}&redirect_uri=${encodeURIComponent(`http://localhost:3000/api/auth`)}`,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }
);

Upvotes: 0

Ethan R
Ethan R

Reputation: 373

According to this issue on the Discord GitHub, this can happen when your body is incorrectly formatted.

After some digging, I saw this post on SO which has led me to believe that you should use URLSearchParams rather than stringifying your json data.

let params = new URLSearchParams();
params.append('client_id', config.clientId);
params.append('client_secret', config.clientSecret);
params.append('code', code);
params.append('grant_type', 'authorization_code');
params.append('redirect_uri', `http://localhost:3000/api/auth`);
params.append('scope', 'identify');

const tokenResponseData = await request(
    'https://discord.com/api/oauth2/token',
    {
        method: 'POST',
        data: params,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    }
);

Upvotes: 1

Related Questions