node.js 在 Express.js 中使用会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14218725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:53:51  来源:igfitidea点击:

Working with Sessions in Express.js

node.jssessionexpress

提问by cesarcruz91

I need help understanding the concept of sessions for a web application. I am running a Node.js server with Express 3.0.

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

My goals are to:

我的目标是:

  • Create a session for each user that logs in

  • Store this session and use it for validating if the user is already logged in (prevent two devices using the same user at the same time) and to limit access to certain pages (by matching session ID to some other data)

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

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

I will be using MemoryStore to save the sessions (seems easiest). If the above goals make sense can you provide a thorough explanation of how to achieve them?

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

回答by zemirco

Express has nice examplesin the github repo. One of them deals with authenticationand shows how to attach the user to the req.sessionobject. This is done inside the app.post('/login')route.

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

To limit access to certain pages add a simple middleware to those routes

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

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>');
});

As Brandonalready mentioned you shouldn't use the MemoryStore in production. Redisis a good alternative. Use connect-redisto access the db. An example config looks like this

正如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 })
}));

回答by Brandon

Use MemoryStore in express ONLY if you are not creating multiple instances (such as with the cluster module). If you are load balancing across machines, your load balancer will need to use sticky / persistent sessions.

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

If you meet those requirements, then all you need to do is upon login, once the credentials are validated, set a session variable to indicate logged in, for example:

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

req.session.loggedIn = true;

If you want to check if a user is logged in, simply check that variable.

如果您想检查用户是否已登录,只需检查该变量即可。

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

You mentioned preventing a single user from having sessions more than one session at a time. To achieve that, you may need to store something in a database indicating that the user is logged in. I warn you, this can be dangerous because of stale sessions. For example, what if a user logs in, but never logs out? What if they close their browser window so the session is gone forever?

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

Express has no concept of an idle session expiration. I have implemented such a thing by storing all sessions in the database along with a last accessed timestamp and then periodically clean up the session data based on the time. But then you need to update your list of who is logged in as well.

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