我有一个基于express,express-session和ws的应用程序(用于websocket支持)。
我已使用此代码启用会话中间件:
app.use(session({secret: 'mysecret',resave: true,saveUninitialized: true,cookie: {}}));
我可以使用以下命令在get处理程序中读取和保存会话变量:
app.get('/', function (req, res) {
res.send('Hello World!');
console.log(req.session.test);
req.session.test="OK";
req.session.save();
});
(第一次打印“undefined”,第二次打印“OK”按预期开始)
现在我有一个websocket服务器,在同一个应用程序中也由express处理,我想在req.session
和ws.on("connection",...)
内获取ws.on("message",...)
对象。
问题是没有对原始req
对象的引用,只是对作为websocket连接处理程序的包装器的upgradeReq
的引用。
检查此upgradeReq我可以在connect.sid
中找到包含会话cookie值的ws.upgradeReq.headers.cookie
。
wss.on('connection', function connection(ws) {
var location = url.parse(ws.upgradeReq.url, true);
console.log(ws.upgradeReq.headers.cookie);
//....
});
在我的想法中,可以通过某种方式从中获取原始req.session
。
我该如何做到这一点?
答案 0 :(得分:7)
好的,我发现了一种研究快速会话源代码的无证方法。
首先,您需要cookie
和cookie-parser
作为您的依赖。
所以,导入模块
var cookie = require('cookie');
var cookieParser = require('cookie-parser')
然后,诀窍是在ws“connection”事件处理程序中对已签名的cookie进行解码,即处理websocket握手时。 首先,您需要从cookie中解码connect.sid作为会话ID(仅当您使用快速会话进行会话管理时)
wss.on('connection', function connection(ws) {
var cookies=cookie.parse(ws.upgradeReq.headers.cookie);
var sid=cookieParser.signedCookie(cookies["connect.sid"],secret);
...
TAke关心您在快递会话中为签名设置的秘密(即app.use(session({secret: secret, resave: true, saveUninitialized: true, cookie: {},store:store}));
)
此时你在sid中有sessoinID,你想从快递会话中获取会话对象,这是从商店异步传递的(有很多,请阅读文档,目前我只测试了MemoryStore of express-session)。
为了获得会话,请在上面的行
之后使用此代码...
store.get(sid,function(err, ss){
store.createSession(ws.upgradeReq,ss)
});
回调函数将直接从商店提供会话对象(ss),但它是单独的,没有方法(只是一个反序列化的JSON)。因此,我们再次使用我们传递upgradeReq和ss对象的store.createSession,这样我就有了一个具有所有记录方法的会话对象(所以我也可以从ws回调中修改会话)。 / p>
新会话对象位于:
ws.upgradeReq.session
保重:
在商店异步返回ss对象之前,会话对象不可用,因此在传递给store.get的回调中完成websocket事件绑定(如on('message',...)
)是一个好习惯。
这是完整的代码:
wss.on('connection', function connection(ws) {
var location = url.parse(ws.upgradeReq.url, true);
//get sessionID
var cookies = cookie.parse(ws.upgradeReq.headers.cookie);
var sid = cookieParser.signedCookie(cookies["connect.sid"], secret);
//get the session object
store.get(sid, function (err, ss) {
//create the session object and append on upgradeReq
store.createSession(ws.upgradeReq, ss)
//setup websocket bindings
ws.on('message', function incoming(message) {
console.log('received: %s', message);
//..........
});
});
});
所以,现在您可以使用ws和express-session一起管理会话数据。
我希望它会有所帮助!
答案 1 :(得分:5)
我刚刚发现版本3.0.0从WebSocket中删除了upgradeReq。现有的alexroat代码的解决方法:
wss.on('connection', function connection(ws, req) {
ws.upgradeReq = req;
var location = url.parse(ws.upgradeReq.url, true);
//get sessionID
var cookies = cookie.parse(ws.upgradeReq.headers.cookie);
var sid = cookieParser.signedCookie(cookies["connect.sid"], secret);
//get the session object
store.get(sid, function (err, ss) {
//create the session object and append on upgradeReq
store.createSession(ws.upgradeReq, ss)
//setup websocket bindings
ws.on('message', function incoming(message) {
console.log('received: %s', message);
//..........
});
});
});