【问题标题】:Session id being same for different client Nodejs不同客户端Nodejs的会话ID相同
【发布时间】:2015-06-18 15:19:03
【问题描述】:

目前我们正在使用express-sessionpassport.jsconnect-redis 在cookie 中设置会话以将数据存储在redis 中。 我有多个节点服务器服务请求。对于没有会话的每个请求,我正在创建一个新会话。有时,现有会话 ID 被分配给新请求。在创建唯一会话之前,我正在检查 cookie 是否存在……如果存在,那么我没有创建新会话。但是在这样做的同时,我们看到相同的会话 ID 与不同的客户端共享。 我怎么知道它是一样的? 第一个用户尝试登录,它成功登录并设置会话并提供有关用户配置文件的正确信息。 第二个用户尝试登录,它成功登录,但将会话设置为前一个,即第一个用户的会话,因此第二个用户在配置文件部分看到第一个用户信息。

Session 实现代码:

function sessionImplementation() {
    return function (req, res, next) {
        if(/ucompany=s%3A/.test(req.headers['cookie'])){
            var cookie = req.headers['cookie'].split("ucompany=s%3A");
            var zCookie = cookie[1].split(".");
            var genid = zCookie[0];
            return session({
                genid:function () {
                    return genid;
                },
                store: redis,
                cookie: {
                    maxAge: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000))
                },
                secret: 'ucomp123',
                resave: false,
                name: "ucompany",
                saveUninitialized: true
            })(req, res, next)

        }
        return session({
            store: redis,
            cookie: {
                maxAge: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000))
            },
            secret: 'ucomp123',
            resave: false,
            name: "ucompany",
            saveUninitialized: true
        })(req, res, next)
    }
}

问题是什么,我该如何解决?

更新 1 根据@robertklep,我已经修改了我的代码。

var express         = require('express');
var session         = require('express-session');
var RedisStore      = require('connect-redis')(session);
var cookieParser    = require('cookie-parser');
var bodyParser      = require('body-parser');
var passport        = require('passport');

var app = express();
app.use(bodyParser.json());// to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compress());
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

//app.use(cookieParser());
var redis = new RedisStore({
  host:config.redis.url,
  port:config.redis.port, 
  prefix:'sess-'+new Date().getDate()+'-'+(new Date().getMonth()+1)+'-'+new Date().getFullYear()+':'
});
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
    store: redis,
    cookie: {
        expires: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000)),
        maxAge:7 * 24 * 60 * 60 * 1000
    },
    secret: 'ucomp123',
    resave: false,
    name: "ucomapny",
    saveUninitialized: true
}));

app.use(passport.initialize());
app.use(passport.session());

【问题讨论】:

  • express-session will handle session cookies itself,所以我不确定你为什么要重新实现它。
  • 什么意思?我没有重新实现任何东西。
  • 您自己解析会话 cookie,并为每个请求重新实例化 express-session 中间件。
  • 在自述文件中,写着app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { secure: true } }))这就是我正在做的。我仍然不明白我正在重新实现相同的意思。不应该是这样的吗?
  • 这绝对是不是你在做什么。尝试使用README 中描述的方法(当然要使用正确的选项),看看是否能解决您的问题。

标签: node.js session cookies express session-cookies


【解决方案1】:

您的代码有几个问题:

  • 不是让express-session 处理会话cookie,而是尝试自己处理它们;
  • 您正在为每个请求实例化会话中间件,这是一种资源浪费,可能也会导致问题(我对 express-session 的研究还不够深,无法做出任何明确的声明);
  • maxAge(对于 cookie)不应该是日期,而是数字(从现在开始 cookie 应该保持有效的毫秒数);您将它与expires 混淆了,它 用于设置时间点;

正常的使用方式是这样的:

var session = require('express-session');
var express = require('express');
var app = express();
...
app.use(session({
  store  : redis,
  cookie : { maxAge : 7 * 24 * 60 * 60 * 1000 },
  secret : 'ucomp123',
  name   : 'ucompany',
  resave : false,
  saveUninitialized : true
});

【讨论】:

  • 我已经完全按照自述文件中的内容和您所展示的内容完成了操作,但是对于两个不同的客户端,我仍然得到相同的会话 ID。例如我看到的这个会话 id 有两个以上的用户:MGpZbwk3qQqaDl2WdqenENIJceC6rBtq
  • @PranayaBehera 不同的客户端是完全不同的浏览器?
  • 是的,对于两个完全不同的用户,具有不同的 ip 以及不同的机器(浏览器)
  • @PranayaBehera 并且您没有使用自定义 genid 函数?两个浏览器都得到了相同的cookie?也没有代理?这听起来很可疑,我怀疑它是由 express-session 引起的。
  • @PranayaBehera 您是否尝试过仅使用一台节点服务器?在您的问题中,您说您正在使用多个服务器。
【解决方案2】:

精灵在哪里?

您必须自己生成它。使用uuid包

【讨论】:

  • 您能详细说明一下吗?也许您可以显示一个带有修复程序的代码 sn-p?
  • app.use(session({ genid: () => { return uuidv4(); // 使用 UUIDv4s 作为会话 ID }, secret: "" + EXPRESSSESSIONSECRET, resave: false, saveUninitialized: true , name: "__session", cookie: myCookie, store: new FirestoreStore({ dataset: ADMIN.firestore(), kind: "express-sessions", }), }));
猜你喜欢
  • 1970-01-01
  • 2012-01-30
  • 2012-06-15
  • 1970-01-01
  • 2011-02-05
  • 2019-02-05
  • 2012-01-22
  • 1970-01-01
  • 2014-07-24
相关资源
最近更新 更多