在Node.js Passport的Google策略上自定义returnUrl

我正在使用Express和Passport OpenID Google战略,并且我想在每个auth请求上设置returnURL以便能够返回到启动该auth的页面。

情况是,我有HTML5幻灯片应用与Node.js后端(与社会的东西和编辑器,门户和扩展… https://github.com/bubersson/humla ),我希望能够login用户一些幻灯片(通过滑动菜单…),但是我希望他能轻松回到相同的幻灯片。

所以我需要这样的东西?

app.get('/auth/google', function(req,res) { var cust = "http://localhost:1338/"+req.params.xxx; passport.authenticate('google', returnURL:cust, function ... } 

我已阅读护照指南,但仍不知道如何去做。 我知道这不是安全的,但我还能怎么做呢?

或者我怎样才能使应用程序返回到login发起的页面? 还是有办法使用AJAX进行OpenID身份validation(仍然可以使用护照)?

我已经想通了我的应用Twitterauthentication,我相信GoogleStrategy是非常相似的。 尝试一下这个变种:

假设您已经从身份validation服务(如护照指南)中定义了回叫路线:

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

只要改变这个块:

 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); }); 

现在,定义您的中间件以获得已authentication的路由,以将原始URL存储在会话中,如下所示:

 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('/'); } 

作品!

无论您拥有哪个loginbutton,都可以将请求的当前URL作为查询参数追加(调整您使用的任何模板系统):

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

然后,将中间件添加到您的GET /auth/google处理程序中,该处理程序将此值存储在req.session

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

最后,在您的callback处理程序中,redirect到会话中存储的URL:

 app.get('/auth/google/callback', passport.authenticate('google', failureRedirect: '/' ), function (req, res) { res.redirect(req.session.redirect || '/'); delete req.session.redirect; }); 

试试res.redirect('back');passport.authenticatecallback

根据作者,这是不可能的OpenID策略。 我们设法通过直接访问variables来dynamic更新这些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); });