Custom returnUrl on Node.js Passport's Google strategy

前端 未结 4 1095
不知归路
不知归路 2020-12-08 05:21

I\'m using Express and Passport OpenID Google strategy and I would like to set returnURL on each auth request to be able to return to the page that initiated that auth.

相关标签:
4条回答
  • 2020-12-08 05:34

    Wherever you have your login button, append the request's current URL as a query parameter (adjust for whatever templating system you use):

    <a href='/auth/google?redirect=<%= req.url %>'>Log In</a>
    

    Then, add middleware to your GET /auth/google handler that stores this value in req.session:

    app.get('/auth/google', function(req, res, next) {
      req.session.redirect = req.query.redirect;
      next();
    }, passport.authenticate('google'));
    

    Finally, in your callback handler, redirect to the URL stored in the session:

    app.get('/auth/google/callback', passport.authenticate('google',
      failureRedirect: '/'
    ), function (req, res) {
      res.redirect(req.session.redirect || '/');
      delete req.session.redirect;
    });
    
    0 讨论(0)
  • 2020-12-08 05:39

    Try res.redirect('back'); in the callback for passport.authenticate

    0 讨论(0)
  • 2020-12-08 05:48

    According to the author this isn't possible with OpenID strategies. We managed to update these dynamically by directly accessing the variables:

    app.get('/auth/google', function(req, res, next) {
      passport._strategies['google']._relyingParty.returnUrl = 'http://localhost:3000/test';
      passport._strategies['google']._relyingParty.realm = 'http://localhost:3000';
      passport.authenticate('google')(req, res, next);
    });
    
    0 讨论(0)
  • 2020-12-08 05:50

    I've figured this out for my apps Twitter authentication, I am sure that the GoogleStrategy is quite similar. Try a variant of this:

    Assuming you have defined the route for the callback from the authentication service like so (from the passport guide):

    app.get('/auth/twitter/callback',
      passport.authenticate('twitter', {
          successRedirect: authenticationRedirect(req, '/account')
        , failureRedirect: '/'
      })
    );
    

    Just change that block to this:

    app.get('/auth/twitter/callback', function(req, res, next){
      passport.authenticate('twitter', function(err, user, info){
        // This is the default destination upon successful login.
        var redirectUrl = '/account';
    
        if (err) { return next(err); }
        if (!user) { return res.redirect('/'); }
    
        // If we have previously stored a redirectUrl, use that, 
        // otherwise, use the default.
        if (req.session.redirectUrl) {
          redirectUrl = req.session.redirectUrl;
          req.session.redirectUrl = null;
        }
        req.logIn(user, function(err){
          if (err) { return next(err); }
        });
        res.redirect(redirectUrl);
      })(req, res, next);
    });
    

    Now, define your middleware for authenticated routes to store the original URL in the session like this:

    ensureAuthenticated = function (req, res, next) {
      if (req.isAuthenticated()) { return next(); }
    
      // If the user is not authenticated, then we will start the authentication
      // process.  Before we do, let's store this originally requested URL in the
      // session so we know where to return the user later.
    
      req.session.redirectUrl = req.url;
    
      // Resume normal authentication...
    
      logger.info('User is not authenticated.');
      req.flash("warn", "You must be logged-in to do that.");
      res.redirect('/');
    }
    

    Works!

    0 讨论(0)
提交回复
热议问题