每次请求都要更改会话

时间:2013-12-28 13:11:22

标签: node.js session redis

我有登录功能

app.post('/doLogin', function(req,res){
        db.users.findOne({username: req.body.username}, function(err, user) {
            if( err ) {
                console.log("Login fail");
            } 
            else if (user != null) {
                if (req.body.password == user.password) {
                    req.session.user_role = "user";
                    req.session.save();
            } else {
                req.session.user_role = "null";
                console.log("Wrong login");
            }
        }
        res.send({redirect: "/"});
    });

});

此函数用于将变量保存到会话req.session.user_role = "user"; 但是当检查用户的新请求是否登录时

app.get('/', function(req,res){
    redis.get('sess:' + req.session.id, function(err, result){
        console.log("Get session: " + util.inspect(JSON.parse(result),{ showHidden: true, depth: null }));
    });
    if ((req.session.user_role == "user")) {
          console.log("Logged in");
    } else {
        console.log("Logged out");
    }
});

然后返回始终为“已注销”,因为会话已更改。我使用Redis存储会话,我认为这是Redis错误,因为当我停止使用Redis时,它没关系 请帮帮我!

5 个答案:

答案 0 :(得分:13)

Express-session 使用Cookie设置或从客户端获取会话ID

documentation

所述
  

请注意,secure:true是推荐选项。但是,它   需要启用https的网站,即HTTPS是安全所必需的   饼干。如果设置了安全性,并且您通过HTTP访问您的站点,则   cookie将不会被设置。

请记住以下几点:

  • 如果您没有在HTTPS连接上托管cookie安全标志应该 设置为false。

  • 如果您使用的是HTTPS上托管的代理,则应设置 信任代理1.参考documentation

以下选项将解决每个请求的会话ID重置问题

cookie: { secure: false }

例如:

app.use(session({
  // your settings
  cookie: { secure: false }
}))

答案 1 :(得分:2)

最好的办法是尽快让Express处理它,如果可以的话。

http://blog.modulus.io/nodejs-and-express-sessions

有一个链接可以向您展示如何在Express中为会话设置redis。在处理会话时,您甚至不必自己查询redis,这是节点中间件的工作。

答案 2 :(得分:1)

可能代码中存在一些异步错误。每次进行异步操作(如回调)时,都应确保在回调函数之后执行其余代码,因此可以将代码放入回调函数中。就像这样:

db.users.findOne({username: req.body.username}, function(err, user) {
  if( err ) {
    console.log("Login fail");
  } 
  else if (user != null) {
    if (req.body.password == user.password) {
      req.session.user_role = "user";
      req.session.save();
      res.send({redirect: "/"});
    } else {
      req.session.user_role = "null";
      console.log("Wrong login");
      res.send({redirect: "/"});
    }
  }
});

app.get应如下所示:

app.get('/', function(req,res){
  redis.get('sess:' + req.session.id, function(err, result){
    console.log("Get session: " + util.inspect(JSON.parse(result),{ showHidden: true, depth: null }));
    if ((req.session.user_role == "user")) {
      console.log("Logged in");
    } else {
      console.log("Logged out");
    }
  });
});

答案 3 :(得分:1)

如果设置了{secure:true},并且您通过HTTP访问了您的网站,则不会设置Cookie。因此,每个请求都将创建一个新会话。

答案 4 :(得分:0)

到目前为止,所有答案都是有帮助的,但不能使用secure:true直接解决问题。

为了使用secure:true,您必须对安全cookie支持https。另外,您必须使用withCredentials进行跨站点访问控制。 withCrendentials:true对同一站点请求没有影响。

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

大多数库在其配置(例如angular和dropzone)中都支持此参数。