I'm struggling with this specific step in the Google OAuth process: "Exchange authorization code for tokens" (As called in Google Developers' "OAuth 2.0 Playground", Step 2).
function getGoogleAuthURL() {
const rootUrl = "https://accounts.google.com/o/oauth2/v2/auth";
const options = {
redirect_uri: `http://${HOST}:${PORT}/auth/google`,
client_id: `${googleConfig.clientId}`,
access_type: "offline",
response_type: "code",
prompt: "consent",
scope: defaultScope.join(" "), // A list of scopes declared in the file scope
};
return `${rootUrl}?${querystring.stringify(options)}`;
}
app.get("/auth/google/url", (req, res) => {
res.redirect(getGoogleAuthURL());
});
After redircting the user to the consent prompt, the code above redirect the user to: http://${HOST}:${PORT}/auth/google, giving the 'Authorization code' necessary to get the refresh and access tokens.
app.get(`/auth/google`, async (req, res) => {
const code = req.query.code
const tokens = await getTokens({code})
});
My problem is coming from the getToken() function that is used to POST and return the tokens.
function getTokens({code}) {
const url = 'https://accounts.google.com/o/oauth2/token';
const values = {
code,
client_id: googleConfig.clientId,
client_secret: googleConfig.clientSecret,
redirect_uri: googleConfig.redirect,
grant_type: 'authorization_code',
};
console.log(`${url}${querystring.stringify(values)}`)
return axios
.post(url, querystring.stringify(values), {
headers: {
'Content-Type': 'application/x-www-form-url-encoded',
},
})
.then((res) => res.data)
.catch((error) => {
throw new Error(error.message);
});
}
I get Error: Request failed with status code 401 from the .catch((error) ...
The console.log(${url}${querystring.stringify(values)}) gives the full built link, which is:
https://accounts.google.com/o/oauth2/tokencode=X&client_id=X.apps.googleusercontent.com&client_secret=X&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3B&grant_type=authorization_code
What I troubleshooted:
I've compared many times my 'request' and 'url' with the ones on Google Developers' "OAuth 2.0 Playground", and the syntax doesn't seem to be the problem with the fields, though I have doubt about the punctuation between /token and code=... that I changed to /token and ?code=..., but still resulting in a failed request (401).
I've also been using two different ${url}:
https://oauth2.googleapis.com/token
https://accounts.google.com/o/oauth2/v2/auth
But I can tell which one I should be using.
The second param of axios post is the body, not query params.
You can set params in the third argument.
You are also missing key for
codein yourvaluesobject.You can also just append the querystring in the first argument: