我有一个简单的身份验证系统,用户可以登录,然后注销。
我的应用中有很多页面和很多路线,每条路线都有这种一般结构(我在这里使用dashboard.hbs
路线作为例子):
router.get('/dashboard', ensureAuthenticated, function(req, res, next) {
User.findOne({ username: req.user.username }, function(err, loggedInUser) {
if (err) throw err
else {
res.render('dashboard', {
user: loggedInUser
})
}
})
});
具体来说,我将loggedInUser
分配给user
以便在我的dashboard.hbs
部分中使用,如下所示:
<h2 align="center">{{user.first_name}}'s Dashboard</h2>
退出时,我只需使用'/logout
路线,如下:
router.get('/logout', function(req, res, next) {
req.logout()
res.render('logout')
});
这种方法的问题在于我在每条路径中重复user: loggedInUser
,我想重构我的代码来干掉它,并定义只登录一次的用户,然后使用它在每个部分。
为了帮助解决此问题,我在server.js
文件中执行了以下操作:
app.use(function (req, res, next) {
res.locals.logged_in_user = req.user
next();
});
现在,我可以在任何部分中使用logged_in_user
而无需在路线中分配它。除了退出时,这在任何地方都可以正常工作。注销时,req.user
属性(分配为logged_in_user
)不会立即删除,并且不会立即清除登录会话。我正在运行以下代码:
router.get('/logout', function(req, res, next) {
req.logout()
res.render('logout')
});
这几乎与Passport文档here完全相同。
一旦我点击/logout
路由,我必须刷新页面以便清除登录会话。当我在每条路线中使用user: loggedInUser
时,情况并非如此。现在它被重构,它不再正常工作。
我还应该注意,我的layout.hbs
文件包含以下代码:
<ul class="nav nav-pills pull-right">
{{#if logged_in_user }}
<li role="presentation"><a href="/dashboard">Dashboard</a></li>
<li role="presentation"><a href="/logout">Log Out</a></li>
<li role="presentation"><a href="/messages">Messages</a></li>
<li role="presentation"><a href="/users/member">Profile</a></li>
{{else}}
<li role="presentation"><a href="/login">Login</a></li>
<li role="presentation"><a href="/register">Register</a></li>
{{/if}}
</ul>
使用重构样式,如何清除用户的登录会话?
更新
虽然res.render('logout')
似乎不起作用,但我可以res.redirect
用户登录页面,并在页面上显示消息(使用connect-flash
)他们已成功记录进行。
答案 0 :(得分:1)
调用req.logout()
将清除req.user
(它基本上是req.user = null
),但是您的中间件创建了对原始对象的引用,这是res.locals.logged_in_user
仍在指向的内容到。
对于会话(req.session.user
):将在响应结束时更新,因此在调用res.render('logout')
之后。这就是为什么在退出后使用res.redirect()
是清除会话的更好方法。