Node.js Passport 的 Google 策略上的自定义 returnUrl
Posted
技术标签:
【中文标题】Node.js Passport 的 Google 策略上的自定义 returnUrl【英文标题】:Custom returnUrl on Node.js Passport's Google strategy 【发布时间】:2012-04-10 18:12:14 【问题描述】:我正在使用 Express 和 Passport OpenID Google 策略,我想在每个身份验证请求上设置 returnURL,以便能够返回到启动该身份验证的页面。
情况是我有带有 Node.js 后端的 html5 幻灯片应用程序(以及社交内容和编辑器以及门户和扩展...https://github.com/bubersson/humla),我希望能够在某些幻灯片上登录用户(通过幻灯片menu...) 但我希望他能轻松回到同一张幻灯片。
所以我需要这样的东西?
app.get('/auth/google', function(req,res)
var cust = "http://localhost:1338/"+req.params.xxx;
passport.authenticate('google', returnURL:cust, function ...
我已阅读 Passport 的指南,但仍然不知道该怎么做。我知道这不安全,但我还能怎么做呢?
或者我怎样才能让应用程序返回到启动登录的页面?或者有没有办法使用 AJAX 进行 OpenID 身份验证(并且仍然可以使用护照)?
【问题讨论】:
【参考方案1】:无论您在哪里有登录按钮,都将请求的当前 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'));
最后,在您的回调处理程序中,重定向到存储在会话中的 URL:
app.get('/auth/google/callback', passport.authenticate('google',
failureRedirect: '/'
), function (req, res)
res.redirect(req.session.redirect || '/');
delete req.session.redirect;
);
【讨论】:
是否可以在没有会话的情况下执行此操作?【参考方案2】:根据作者的说法,这对于 OpenID 策略是不可能的。我们设法通过直接访问变量来动态更新这些:
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);
);
【讨论】:
【参考方案3】:我已经为我的应用程序 Twitter 身份验证解决了这个问题,我确信 GoogleStrategy 非常相似。试试这个的变体:
假设您已经像这样定义了来自身份验证服务的回调路由(来自护照指南):
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);
);
现在,为经过身份验证的路由定义中间件,以将原始 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('/');
有效!
【讨论】:
这很好用,但是在重定向时,如果用户被发送出去进行身份验证并返回,它似乎缺少哈希参数。登录后重定向时,是否有某种方法可以将它们保留在 URL 中? ***.com/questions/14124932/… @user645715 可以尝试使用req.session.redirectUrl = req.originalUrl;
或req.url
【参考方案4】:
在passport.authenticate
的回调中尝试res.redirect('back');
【讨论】:
谢谢!显然,在第一个和第二个 OpenID 请求之间设置了反向路由。我不知道!谢谢 嗯,我发现了这个问题。只有当我已经使用 Google 登录时,它才有效。如果护照重定向到谷歌页面,然后返回到我的网站 - “页面”路线丢失。是否有其他方法可以强制它从 Google 返回到我的位置(启动登录的页面)? @bubersson,如果我理解正确的话,您需要使用更主动的方法,例如第一个答案中的方法。以上是关于Node.js Passport 的 Google 策略上的自定义 returnUrl的主要内容,如果未能解决你的问题,请参考以下文章
使用 passport.js 将本地策略连接到另一个(Facebook、Twitter、Google 等)
如何允许用户在 Node JS Passport JS 失败后尝试不同的电子邮件?
我可以使用 passport-google 回调来验证 android/ios 用户吗?
Passport & JWT & Google/Facebook 策略 - 如何结合 JWT 和 Google/Facebook 策略?