I've been stuck for hours getting the Google OAuth2 flow going in my Node/Express application. The basics are fairly straight-forward:
- Create Google application credentials
- Redirect users to consent screen
- Receive a
codevalue - Exchange
codeforaccess_tokenandrefresh_token - Store
refresh_tokenfor the future
For whatever reason, I cannot pass Step 4 above and always get the following response:
{
"error": "invalid_grant",
"description": "Bad Request"
}
There are a ton of other solutions asking about the above, and no solution has yet worked for me:
- Don't use the same
coderegardless of result - Wait a while after adding new Authorized Redirect URIs
- Include http://localhost:3000 as an Authorized Redirect URI
- Include all variants with/without protocol, port, trailing-slash
- Set
access_typeto offline previously if needed (and it is) - Use Request instead of Axios
- Include a null
scopeparameter like the OAuth Playground - Encode parameters using Querystring
- Confirm
application/x-www-urlencodedis the Content-Type - Log out of all Google accounts when retrying
- Be aware of Google's token creation limit
With the above stated, here's the specifics of my plight:
Host: http://localhost:3000
Callback #1: http://localhost:3000/auth/google/callback (where code is sent and exchange action below is run)
Callback #2: http://localhost:3000/auth/google/callbacktwo (where access_token and refresh_token should be returned)
Exchange Action: Adjusted for Request module
{
method: 'POST',
uri: 'https://www.googleapis.com/oauth2/v4/token',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
body: {
'code': req.query.code,
'redirect_uri': 'http://localhost:3000/auth/google/callbacktwo',
'client_id': '***.apps.googleusercontent.com',
'client_secret': '***',
'scope': null,
'grant_type': 'authorization_code'
}
}
Authorized Redirect URIs: Visible in Application > Credentials > OAuth 2.0 client IDs
All-in-all, I'm stuck. There's either something fundamentally wrong with my setup/approach or I'm the first developer encountering this bug (the latter can't be true). Can pay for assistance too.