不同客户端Nodejs的会话ID相同
Posted
技术标签:
【中文标题】不同客户端Nodejs的会话ID相同【英文标题】:Session id being same for different client Nodejs 【发布时间】:2015-06-18 15:19:03 【问题描述】:目前我们正在使用express-session
与passport.js
和connect-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
中描述的方法(当然要使用正确的选项),看看是否能解决您的问题。
【参考方案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", ), ));以上是关于不同客户端Nodejs的会话ID相同的主要内容,如果未能解决你的问题,请参考以下文章
在 Node JS 中从不同的“会话”读取/写入相同的文件内容是不是有风险?
NodeJS、VueJS、快速会话。 cookie 不在客户端设置
php 会话控制(了解cookie与session之间的区别与联系)