我正在尝试使用node.js,express和passport.js Build 登录机制 . 登录本身工作得很好,会话与redis很好地存储,但我确实有一些麻烦,在提示进行身份验证之前将用户重定向到他开始的位置 .
例如用户跟随链接 http://localhost:3000/hidden
然后重定向到 http://localhost:3000/login
但我希望他再次重定向回 http://localhost:3000/hidden
.
这样做的目的是,如果用户随机访问他需要首先登录的页面,他将被重定向到提供其凭据的/ login站点,然后被重定向回他之前尝试访问的站点 .
这是我的登录帖子
app.post('/login', function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err)
} else if (!user) {
console.log('message: ' + info.message);
return res.redirect('/login')
} else {
req.logIn(user, function (err) {
if (err) {
return next(err);
}
return next(); // <-? Is this line right?
});
}
})(req, res, next);
});
在这里我的ensureAuthenticated方法
function ensureAuthenticated (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
它挂钩到 /hidden
页面
app.get('/hidden', ensureAuthenticated, function(req, res){
res.render('hidden', { title: 'hidden page' });
});
登录站点的html输出非常简单
<form method="post" action="/login">
<div id="username">
<label>Username:</label>
<input type="text" value="bob" name="username">
</div>
<div id="password">
<label>Password:</label>
<input type="password" value="secret" name="password">
</div>
<div id="info"></div>
<div id="submit">
<input type="submit" value="submit">
</div>
</form>
7 回答
我不知道护照,但这是我的方式:
我有一个中间件我用
app.get('/account', auth.restrict, routes.account)
在会话中设置redirectTo
然后我重定向到/ login然后在
routes.login.post
我执行以下操作:在你的
ensureAuthenticated
方法中保存会话中的返回URL,如下所示:然后,您可以将passport.authenticate路线更新为:
看看connect-ensure-login,它与Passport一起工作,完全符合您的要求!
如果您正在使用connect-ensure-login,则可以使用
successReturnToOrRedirect
参数通过Passport以超级简单的集成方式执行此操作 . 使用时,护照会将您发送回最初请求的URL或回退到您提供的URL .https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to
我的做事方式:
GET /login 控制器:
POST /login 控制器:
POST /logout 控制器(不确定是否有100%正常,欢迎评论):
Clear returnTo middleware (在除auth路由之外的任何路由上清除returnTo - 对我来说它们是/ login和/ auth /:provider):
这种方法有 two features :
你可以使用isAuthenticated中间件保护一些路由;
在任何页面上你只需点击登录URL,登录后返回该页面;
如果用户在登录重定向后进入另一个页面(这不需要身份验证)并通过那里登录,则@chovy和@linuxdan的答案有 bug 而不清除
session.returnTo
. 因此,将此代码添加到其实现中:如果您从登录页面执行一些ajax请求,您也可以将它们排除在外 .
另一种方法是在
ensureAuthenticated
中使用 flash然后在GET登录
在视图中添加隐藏字段到登录表单(例如在玉中)
在POST登录
请注意,redirectTo将在首次GET登录后清除 .
最简单(和正确)的方法是setting failureRedirect and successRedirect options .