Express-session:第一个用户会话被第二个用户会话覆盖

Express-session: first user session overwritten by second user session

本文关键字:会话 用户 第二个 覆盖 Express-session 第一个      更新时间:2023-09-26

这是一个get请求,用户被传递到视图

app.get('/blog/:id', function(req, res) {
  // Define which page
  res.render('blog', {
    user: req.user,
});
}); 

这是一个文本区,该页面上的所有用户都应该存储他们的名字。

<textarea readonly id="usersInRoom" placeholder="<%= user.username %>"></textarea>

这将成功设置正确的用户名作为占位符。如果第二个用户呈现相同的视图并与第一个用户同时访问此页面,则第二个用户的用户名将是唯一的占位符。如何存储第一个用户名,以便当第二个用户打开页面时,占位符可以是第一个用户名+第二个用户名的串联?第一个用户存储在任何嵌入式javascript数组等中的数据对第二个用户不可用。

如果您正在使用SignalR,那么您可以向每个连接广播当前用户列表并更新视图,就像在示例聊天应用程序中一样。

如果您使用的是常规ajax服务器轮询,请设置一个客户端方法,该方法间隔从数据库存储获取当前页面用户列表。由于http缺乏状态,如果用户有一段时间没有发帖,你将不得不把他们从列表中"退休"。

客户机代码:

setInterval(checkServer,5000);
function checkServer(){
    //some ajax call to the server here 
    //that returns your user list
    ...
    success:function(result){
       $('#usersInRoom').val(result);
    }
}

服务器代码(假设您将所有当前页面用户保存在一个表中)包含一个名为LastModified的字段):

CurrentPageUser类(将其存储在DbContext中作为CurrentPageUsers表):

public class CurrentPageUser{
   public int Id {get;set;}
   public DateTime LastModified {get;set;}
   public string Name {get;set;}
}
控制器方法:

public string GetCurrentUsers(int selfid){
    using (var db=new DbContext()){
       var now=DateTime.Now;
       //update your requesting user so other users can see him/her
       db.CurrentPageUsers.Find(selfid).LastModified=now;
       db.SaveChanges();
       DateTime timelimit = now.AddMinutes-5);
       return string.Join(", ",
         db.CurrentPageUsers.Where(u=>
            u.LastModified<timelimit).Select(u=>u.Name).ToList());
    }
}

请注意,SignalR的实现具有更好的性能,并且在服务器端实现时不那么笨拙,不需要数据库表来存储当前页面用户。

我找到了一个解决方案。事实上,我确实有express-session来保存我的登录会话。第一个会话被第二个用户覆盖,这个用户在第一个用户在线时登录,它用第二个用户替换了第一个用户的凭据,现在我在两个不同的浏览器中有用户2在线。

虽然我在不同的浏览器上尝试了这个,从不同的设备,问题是节点应用程序在本地托管在localhost。当我将应用程序上传到heroku并从那里访问它时,用户会话没有被覆盖。