【问题标题】:Passport 'logout()' not working as expected护照“注销()”没有按预期工作
【发布时间】:2017-07-09 15:31:35
【问题描述】:

我有一个简单的身份验证系统,用户可以登录,然后退出。

我的应用中有很多页面和很多路由,每条路由都有这样的一般结构(我这里以我的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)他们已成功注销。

【问题讨论】:

    标签: session express passport.js


    【解决方案1】:

    调用req.logout() 将清除req.user(基本上是req.user = null),但您的中间件创建了对原始对象的引用,而res.locals.logged_in_user 仍然指向该对象。

    至于会话 (req.session.user):将在响应结束时更新,因此在调用 res.render('logout') 之后。这就是为什么使用res.redirect() 是注销后清除会话的更好方法。

    【讨论】:

    • 对于这种情况,使用res.redirect() 是否被认为比res.render() 更好?我问是因为从技术上讲,如果我不使用res.locals.logged_in_user = req.user,我仍然可以使用res.render('logout'),并且只需在我的应用程序的每条路线中定义user: loggedInUser
    • @Farid 你也可以在渲染调用中覆盖logged_in_userres.render('logout', { logged_in_user : null })。如果您有特定的“已注销”页面,则呈现页面而不是重定向就可以了。
    • 这是个好主意。我没想到。谢谢!
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    相关资源
    最近更新 更多