Search code examples
node.jsgoogle-oauthgoogle-api-nodejs-client

google-api-nodejs-client throws invalid_request error when exchanging code with tokens


I've got a simple client app using react-google-login with this settings:

<GoogleLogin
        clientId={config.CLIENT_ID}
        scope={config.SCOPES.join(' ')}
        buttonText="Login With Google"
        onSuccess={response => onSignIn('google', response)}
        onFailure={this.failure.bind(this)}
        accessType="offline"
        responseType="code"
      />

It retrieves the code successfully and sends it to the backend server which is written with NodeJS.

The server-side code looks like this:

const { google } = require('googleapis');
const config = global.config;
const oauth2Client = new google.auth.OAuth2({
  clientId: config.google.CLIENT_ID,
  clientSecret: config.google.CLIENT_SECRET,
});

// code omitted for the sake of simplicity

var authCode = req.body.authCode; // the provided code by google

const { tokens } = await oauth2Client.getToken(authCode);
return tokens;

When I run the code, it throws the error:

{ error: 'invalid_request',
        error_description: 'Missing parameter: redirect_uri' } },
  code: '400' }

and if I add redirectUrl to Developer Console, client app and server-side app, I'll get redirect_uri_mismatch error.

I'm kind of stuck here and couldn't find anything useful on the web.

Any workaround would be appreciated.


Solution

  • Found the solution

    Based on one of the replies (surprisingly, not the answer) on this post,

    All I needed to do was put postmessage instead of the actual URL in my client react-google-login button and in oauth2Client config on the server.

    no need for the redirect_uri on Developer Console at all.

    <GoogleLogin
                clientId={config.CLIENT_ID}
                ****redirectUri="postmessage"****
                scope={config.SCOPES.join(' ')}
                buttonText="Login With Google"
                onSuccess={response => onSignIn('google', response)}
                onFailure={this.failure.bind(this)}
                accessType="offline"
                responseType="code"
              />
    
    const oauth2Client = new google.auth.OAuth2({
      clientId: config.google.CLIENT_ID,
      clientSecret: config.google.CLIENT_SECRET,
      ****redirectUri: 'postmessage'****
    });
    

    Did solve the issue. 5 hours of working, searching and beating my head to the desk. I wonder why there's no clear documentation on Google Developers website. Or maybe there are and I couldn't find them.