#Invalid_Grant error for OAuth 2.0

50 messages · Page 1 of 1 (latest)

jagged marsh

Goal for me was to initiate a redirect (in the server side) on my web app after I receive user information from discord authentication then use that information to populate the specified page that was being redirected to. Problem is I am getting an invalid_grant error with an error description of invalid "code" in my GET request. I made sure the redirect URIs were matching throughout; made sure there werent any other request calls being made at the same time; I am currently using express as my server and using express session to store my state and userinfo and axios to do my HTTP requests. I am also getting the user_info, the problem happens when it does a redirect on the server side. I am just lost in figuring out how to better diagnose this; any advice is really helpful. Does "invalid code" refer to the code used to exchange for the access token?

humble ledgeBOT
  • Consider reading #how-to-get-help to improve your question!
  • Explain what exactly your issue is.
  • Post the full error stack trace, not just the top part!
  • Show your code!
  • Issue solved? Press the button!
  • Marked as resolved by OP
jagged marsh
//client side request
const response = await axios.get(`https://localhost:_____/auth/callback?code=${code}&state=${state}&redirect=${encodeURIComponent(redirect)}`, {
      withCredentials: true, // Ensure credentials are included
    });
Error response data: {
  error: 'invalid_grant',
  error_description: 'Invalid "code" in request.'
}
Error response status: 400
Error response headers: Object [AxiosHeaders] {
  date: '',
  'content-type': 'application/json',
  'content-length': '79',
  connection: 'keep-alive',
  'cache-control': 'no-store',
  pragma: 'no-cache',
  'set-cookie': [
    '__dcfduid=59c89f9a199411efb52496b81cf4e3c6; Expires=Wed, 23-May-2029 06:10:42 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax',
    '__sdcfduid=59c89f9a199411efb52496b81cf4e3c6f6a0733cf375106fe42f53996624652846ff84b51ffe23e72d97909040d0eddb; Expires=Wed, 23-May-2029 06:10:42 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax',
    '__cfruid=c3dec741acb51d07e62de15bf0586d06bacc74b6-1716531042; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None',
    '_cfuvid=ITAbKiFgINcOrXciQ0XU.hv0lOK6glW0LTYGgBUSNZA-1716531042409-0.0.1.1-604800000; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None'
  ],
  'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
  via: '1.1 google',
  'alt-svc': 'h3=":443"; ma=86400',
  'cf-cache-status': 'DYNAMIC',
  'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=ccHDQwnmVDXDg4MZZxaV0w1%2B%2FEl0MK5zehhyQo9g29WU71gmlw6ZpMn%2BbuZVvZzuTXLEGydhfFTtd9RyxHUDysHv5MrQyAEmM%2FPsm3blcthkITLOy83C%2F2VjByLH"}],"group":"cf-nel","max_age":604800}',
  nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
  'x-content-type-options': 'nosniff',
  'content-security-policy': "frame-ancestors 'none'; default-src 'none'",
  server: 'cloudflare',
  'cf-ray': '888b1fc5dba29023-BOS'
}
timid dragon
jagged marsh
timid dragon

right, but is this after calling https://discord.com/oauth2/authorize?

jagged marsh

Yeah

With the intended scope, client id, etc

Heres what it looks like:

https://discord.com/api/oauth2/authorize?client_id=${process.env.CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&scope=identify&state=${state}&redirect=${encodeURIComponent(redirect)}

Im fairly sure it might have to do with something in my /auth/callback handler but idk what

timid dragon

up until the user info part, anyway

where exactly is the error happening?

jagged marsh

From my logs it looks like its happening right after it tries to grab userinfo with the access token

timid dragon

ok one sec

i didn't copy that part

jagged marsh

Weird thing is I still get the user object

But I get a CORS and the error I mentioned above

I tried returning the user object as a response rather than redirecting and handled the redirecting on the client side but it was a temporary fix and not consistent as the error peristed but not as much as previous implementation

timid dragon

so this log is working? console.log('User info:', userInfo.data);

jagged marsh

Yes

And when logging the session you should be able to see the object as well

timid dragon

then it seems like the issue is somewhere else

jagged marsh

Gahhhh

Any idea what it could be

timid dragon

probably in what happens after the redirect

jagged marsh

Im not on my pc rn unfortunately

Mmmmmmmm

When I logged the redirect I would get a CORS error but I did set an origin when setting up the server before the handler calls

So heres what my approach was;

I do the discord auth -> I get code -> I do a get request on the client side to get the access token which will be used to get user info -> populate user info in session -> redirect to another page where it will call another get handler that will give user info from session

Idk if this makes sense

civic olive

Is the second handler using the code again or the access token?

jagged marsh

Its actually just using express session to retrieve user jnfo

I save the content when reteieving the object the first time using the code and access token

Sodey if mynspelling is bad im a horroble texter

civic olive

If you're already using express, it would probably be easier for you to do the entire flow on the server, then just have an endpoint for the client to get it's user info with a cookie or something alike

jagged marsh

Mmmmm yeah..... now that you point that out it makes a lot of sense actually lol

Ill try that out when I get back

Any best pracfices you recommend when implementing this flow

Almost gorgot to thank you btw haha

civic olive

The guide page already has a pretty good setup for this https://discordjs.guide/oauth2/#authorization-code-grant-flow

I've setup a couple and I usually do it this way: (but you can change it a bit for your needs)

  • -> GET /auth/discord
    ** -> Check for code query, if valid, continue with verification, if not, redirect to the discord auth url.
    ** -> Create your own token for this session. Store user information in a db of some sort, by user id or token. save the token as a cookie for the request.

Something else I've done is use the state parameter to store redirect information (encoded in base64). You just need to verify the redirect is only for the same site as yours.

jagged marsh

Awesome thank you!

civic olive

no problem!

jagged marsh

Just another question before I pass out lol but will thos thread be removed and if so how long will that be

Cause I want to review what you share when implementing but afraid rhat it might go away or something

civic olive

I don't think so unless you mark it as solved or smth

You could always just copy my message in a note apps or smth

jagged marsh

Yeah you right best I should do that rn before I forget 😂