37

我需要帮助来理解 Web 应用程序的会话概念。我正在使用 Express 3.0 运行 Node.js 服务器。

我的目标是:

  • 为每个登录的用户创建一个会话

  • 存储此会话并将其用于验证用户是否已登录(防止两台设备同时使用同一用户)并限制对某些页面的访问(通过将会话 ID 与其他一些数据匹配)

我将使用 MemoryStore 来保存会话(似乎最简单)。如果上述目标有意义,您能否详细解释如何实现这些目标?

4

2 回答 2

42

Express在 github repo 中有很好的例子。其中之一处理身份验证并显示如何将用户附加到req.session对象。这是在app.post('/login')路线内完成的。

要限制对某些页面的访问,请向这些路由添加一个简单的中间件

function restrict(req, res, next) {
  if (req.session.user) {
    next();
  } else {
    req.session.error = 'Access denied!';
    res.redirect('/login');
  }
}

app.get('/restricted', restrict, function(req, res){
  res.send('Wahoo! restricted area, click to <a href="/logout">logout</a>');
});

正如Brandon已经提到的,您不应该在生产中使用 MemoryStore。Redis是一个不错的选择。使用connect-redis访问数据库。示例配置如下所示

var RedisStore = require('connect-redis')(express);

// add this to your app.configure
app.use(express.session({
  secret: "kqsdjfmlksdhfhzirzeoibrzecrbzuzefcuercazeafxzeokwdfzeijfxcerig",
  store: new RedisStore({ host: 'localhost', port: 3000, client: redis })
}));
于 2013-01-08T22:15:09.033 回答
10

仅当您不创建多个实例(例如使用集群模块)时,才在 express 中使用 MemoryStore。如果您要跨机器进行负载平衡,您的负载平衡器将需要使用粘性/持久会话。

如果您满足这些要求,那么您需要做的就是在登录时,在验证凭据后,设置一个会话变量以指示已登录,例如:

req.session.loggedIn = true;

如果要检查用户是否登录,只需检查该变量。

if (req.session.loggedIn) {
    // user is logged in.
}
else {
    // user is not logged in.
}

您提到防止单个用户一次拥有多个会话。为了实现这一点,您可能需要在数据库中存储一些指示用户已登录的内容。我警告您,由于会话过时,这可能很危险。例如,如果用户登录但从未注销怎么办?如果他们关闭浏览器窗口以使会话永远消失怎么办?

Express 没有空闲会话到期的概念。我通过将所有会话与上次访问的时间戳一起存储在数据库中来实现这样的事情,然后根据时间定期清理会话数据。但是,您还需要更新您的登录列表。

于 2013-01-08T19:35:05.473 回答