As @BenFortune already mentioned, I sent the GET parameters as a POST request. It is amazing that such a trivial thing went unnoticed, trying to understand it for more than an hour.
Now I blame the inconsistencies between the OAuth providers for this. In the same application, I make a Facebook GET request to get access_token : https://graph.facebook.com/oauth/access_token . But Google is expecting a POST request to get access_token : https://accounts.google.com/o/oauth2/token
The correct version is:
var url = 'https://accounts.google.com/o/oauth2/token'; var payload = { grant_type: 'authorization_code', code: req.body.code, client_id: req.body.clientId, client_secret: 'HIDDEN', redirect_uri: req.body.redirectUri }; request.post(url, { form: payload }, function(error, response, body) { console.log(body); });
source share