2

I have a route on my backend application which should return an access token for a code sent from the frontend:

router.get('/token', (req, res) => {
  const auth = googleService.getAuth();

  auth.getToken(req.query.code, (error, res2) => {
    const data = { code: 200 }

    if (error) {
      data.code = error.code;
      data.error = error.response.data;
    } else {
      console.log(res2);
    }

    res
      .status(data.code)
      .send(data);
  })
});

I retrive auth from googleService.getAuth():

const { google } = require('googleapis');
const keys = require('../config/keys');

var module = module.exports = {
  getAuth: (token = false) => {
    let auth = new google.auth.OAuth2(
      keys.google.clientID,
      keys.google.clientSecret,
      keys.google.callbackURL
    );

    if (token) {
      auth.credentials = {
        access_token: token,
        refresh_token: null
      };
    }

    return auth;
  },
  youtube: google.youtube('v3')
};

In my config file, I have callbackURL:

module.exports = {
  google: {
    apiKey: 'XXXXXXXXXXXXXXXX',
    clientID: 'XXXXXXXXXXXXXX',
    clientSecret: 'XXXXXXXXXXXXXXX',
    callbackURL: 'http://localhost:3000/google/redirect'
  }
}

I also set it in my console:

enter image description here

However, I always have the following error when calling this route:

"error": {
  "error": "redirect_uri_mismatch",
  "error_description": "Bad Request"
}
Raphael
  • 563
  • 1
  • 10
  • 22

2 Answers2

1

The uri needs to match from the auth to the token. So it looks like you auth via your token endpoint and try to send the token to the google/redirect path. You can work around this.

To do so, verify that the redirect uri is whitelisted in your google project console. You can view this via the API Access (where you would see client ID, client secret, as well as a list of redirect uris)

Phil
  • 175
  • 1
  • 1
  • 13
  • I'm not sure to really understand. I added `http://localhost:3000` in 'Authorized Javascript Origins' and it doesn't change anything [Screenshot](https://i.imgur.com/ZaGvio4.png) – Raphael Mar 27 '19 at 17:45
  • You are asking google for a token via `http:localhost:3000/token` and you are trying to send that token to `http:localhost:3000/google/redirect` this is causing the uri mismatch error. You should be able to add the uri you want to send the token to a list in your project console. – Phil Mar 27 '19 at 17:47
  • 1
    I still don't understand. I don't login from the backend, but from the frontend where I got a code which a send to the backend. There's no need to redirect to any route, however, the API is asking me to. [I also inspired myself from this](https://stackoverflow.com/questions/43930184/get-access-token-on-server-side-javascript-nodejs-using-google-authorization-c) What should I do ? – Raphael Mar 27 '19 at 17:56
  • right so you login to the FE and ask your BE to handle asking google for a token. You give google your creds (clientId + secret) in exchange for a token. The issue is where you asked for the token is not the same as where the token is supposed to go. The difference in the uri then throws the error you get. In order to overcome this, you need to tell google, 'hey that `google/redirect` guy is with me, he's cool'. Google just compares `http://localhost:3000/token` to `http://localhost:3000/google/redirect`. Obviously these are the same, thus the error. – Phil Mar 27 '19 at 18:07
  • In order to overcome this error, you need to whitelist `http://localhost:3000/google/redirect`. Go to your google project, go to the api access section and add that url and try again. – Phil Mar 27 '19 at 18:09
  • Is it in the "Client ID for Web application" page, because if it's the case I already added it on my previous [Screenshot](https://i.imgur.com/ZaGvio4.png) or is it [this page](https://i.imgur.com/muuXckI.png) ? I cannot add localhost address on this page – Raphael Mar 28 '19 at 15:26
  • You are almost there. The 'Client ID..' page is the one you want for the redirect uri, however you also need to add the url to the Authorized Domains page as well. So in your other image I see two errors. It says don't include the protocol and don't include the port. Try adding this: `localhost/google/redirect`. If that doesn't work try adding just `localhost` – Phil Mar 28 '19 at 16:05
  • 2
    I finally got it! But I didn't use anything that you mentioned lol. In my code, I changed `callbackURL` to `https://localhost:4200` which is the address where my frontend is hosted, and on the console, I added `https://localhost:4200` to the Authorized redirect URIs in the "Client ID for Web application" page. Even though this is a very strange configuration, everything is fine now! – Raphael Mar 28 '19 at 16:13
  • Ahh I see, I didn't realize the role your FE was having here. Anyways, that's great I'm glad you were able to figure it out! One takeaway to look into: Is it a requirement to use a secure protocol in the redirect uris now (wasn't the case previously). Cheers! – Phil Mar 28 '19 at 16:50
0

It's possible that you can't have a redirect URI that is local.

If so, you can have an http valid address for you localhost in 2 mins with https://ngrok.com

Hope it'll help

thibautj
  • 76
  • 6