jaredhanson / passport-google-oauth

Google authentication strategies for Passport and Node.js.
https://www.passportjs.org/packages/passport-google-oauth/?utm_source=github&utm_medium=referral&utm_campaign=passport-google-oauth&utm_content=about
MIT License
775 stars 327 forks source link

Dynamic callbackURL #74

Open lukezheng opened 9 years ago

lukezheng commented 9 years ago

I'm using a dynamic way to assign the callbackUrl for Google OAuth. Aka

    passport.authenticate( 'google',
    {
      scope: scope,
      accessType: 'offline',
      approvalPrompt: 'force',
      callbackURL: "http://" + req.host + "/authed/google"
    } );

where req.host can change dynamically. However, in my callbackURL, I'll need to re-authenticate again,

  app.get( '/authed/google', passport.authenticate( 'google',
  {
    callbackURL: 'Should be the same as the first call',
    failureRedirect: '/auth/failure',
    successRedirect: '/auth/success'
  } ) );

Is there a way to pass the callbackURL from the first passport.authenticate() to the callback, so the callback's passport.authenticate() can use the same one?

If the urls aren't matching, it'll cause a

failed to obtain access token (status: 400 data: {
  "error" : "redirect_uri_mismatch"
})
    at /Users/lukezheng/git/spoton/business/node_modules/passport-google-oauth/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth2.js:126:38
    at /Users/lukezheng/git/spoton/business/node_modules/passport-google-oauth/node_modules/passport-oauth/node_modules/oauth/lib/oauth2.js:177:18
    at passBackControl (/Users/lukezheng/git/spoton/business/node_modules/passport-google-oauth/node_modules/passport-oauth/node_modules/oauth/lib/oauth2.js:124:9)
    at IncomingMessage.<anonymous> (/Users/lukezheng/git/spoton/business/node_modules/passport-google-oauth/node_modules/passport-oauth/node_modules/oauth/lib/oauth2.js:143:7)
    at IncomingMessage.emit (events.js:117:20)
    at _stream_readable.js:943:16
    at /Users/lukezheng/git/spoton/business/node_modules/newrelic/node_modules/continuation-local-storage/node_modules/async-listener/glue.js:188:31
    at process._tickDomainCallback [as _tickCallback] (node.js:463:13)
bachvtuan commented 8 years ago

The same situation here. I use google passport to authenticate Google Drive and Youtube. when I make custom callback for youtube, Passport always use default callback from Google Drive.

jayachakladar commented 8 years ago

I use google passport to create new users in the system, and also to link an existing local users to its google account. In each of these cases, my redirect needs to be different(new user comes into dashboard and logged in user stays in the page from where the linking has been requested). Is there a way to achieve that, other than dynamic callbackurl ? Or is it again a dynamic callback url support that is required.

natario1 commented 8 years ago

Any solution to this guys?

bachvtuan commented 8 years ago

@natario1 In my case, I use same url for authenticate via Google Drive and Youtube. After I get the token ( not sure it's from Google Drive or Youtube ) I need to request to https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={returned_token} to get the scope. Then you can see it's youtube or google_drive. Good luck !

tomivm commented 3 years ago

this work for me.

const configureGoogleStrategy = app => {
  let domain;
  app.get('/login/google', (req, res, next) => {
    domain = req.headers.referer;
    //if referer is private insert default hostname
    if (!domain) {
      domain = 'https://app.cboard.io/';
    }
    return passport.authenticate('google', {
      session: false,
      scope: config.google.SCOPE,
      callbackURL: domain + config.googleCallbackPath
    })(req, res, next);
  });

  // GET /login/google/callback
  //   Use passport.authenticate() as route middleware to authenticate the
  //   request.  If authentication fails, the user will be redirected back to the
  //   login page.  Otherwise, the primary route function function will be called,
  //   which, in this example, will redirect the user to the home page.
  app.get(
    '/login/google/callback',
    (req, res, next) => {
      return passport.authenticate('google', {
        callbackURL: domain + config.googleCallbackPath,
        failureRedirect: '/',
        session: false
      })(req, res, next);
    },
    (req, res) => {
      res.json(req.user);
    }
  );
};