Node.js、ws 和 express-session : how to get session object from ws. upgradeReq

标签 node.js session express websocket express-session

我有一个基于 express、express-session 和 ws(用于 websocket 支持)构建的应用程序。

我已经使用这段代码来启用 session 中间件:

app.use(session({secret: 'mysecret',resave: true,saveUninitialized: true,cookie: {}}));

我可以在 get 处理程序中读取和保存 session 变量:

app.get('/', function (req, res) {
  res.send('Hello World!');
  console.log(req.session.test);
  req.session.test="OK";
  req.session.save();
});

(第一次打印“undefined”,第二次按预期打印“OK”)

现在我在同一个应用程序中也有一个由 express 处理的 websocket 服务器,我想在 ws.on("connection", ...)ws.on("message",...)

问题是没有对原始 req 对象的引用,只是对 upgradeReq 的引用,它是 websocket 连接处理程序的包装器。 检查此 upgradeReq,我可以在包含 session cookie 值的 ws.upgradeReq.headers.cookie 中找到 connect.sid

wss.on('connection', function connection(ws) {
  var location = url.parse(ws.upgradeReq.url, true);
  console.log(ws.upgradeReq.headers.cookie);
  //....
});

在我看来,可以通过某种方式从中获取原始的 req.session

我怎样才能做到这一点?

最佳答案

好的,我找到了一个未记录的方法来研究 express-session 的源代码。

首先你需要cookiecookie-parser作为你的依赖。

所以,导入模块

var cookie = require('cookie');
var cookieParser = require('cookie-parser')

然后,诀窍是在有 websocket 握手时解码 ws“连接”事件处理程序中的签名 cookie。 首先,您需要从 cookie 中解码 connect.sid,即 session ID(仅当您使用 express-session 进行 session 管理时)

wss.on('connection', function connection(ws) {
    var cookies=cookie.parse(ws.upgradeReq.headers.cookie);
    var sid=cookieParser.signedCookie(cookies["connect.sid"],secret);
    ...

请注意, secret 与您在 express-session 中为签名设置的 secret 相同(即在 app.use(session({secret: secret, resave: true, saveUninitialized: true, cookie: {},商店:商店})); ) 此时你在 sid 中​​有 sessoinID,你想从 express-session 中获取 session 对象,它是从商店异步传递给你的(有很多,阅读文档,目前我只测试了express-session 的 MemoryStore)。

为了获得 session ,请在上面几行之后使用此代码

...
store.get(sid,function(err, ss){
        store.createSession(ws.upgradeReq,ss)
    });

回调函数将直接从存储中为您提供 session 对象 (ss),但它是单独的且没有方法(只是反序列化的 JSON)。因此,出于这个原因,我们再次使用我们将 upgradeReq 和 ss 对象传递给的 store.createSession,这样我就有了一个 session 对象,它具有所有记录的方法(因此我也可以从 ws 回调修改 session )。

新 session 对象可用于:

ws.upgradeReq.session

注意: 在存储异步返回 ss 对象之前, session 对象不可用,因此最好在回调内完成 websocket 事件绑定(bind)(如 on('message',...)传递给 store.get。

这是完整的代码:

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 来管理 session 数据。

希望对您有所帮助!

关于Node.js、ws 和 express-session : how to get session object from ws. upgradeReq,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36842159/

相关文章:

javascript - 为什么不显示 ' admin' 页面?

javascript - 类型错误 : Cannot read property 'apply' of undefined at EventEmitter

javascript - 这是什么错误{ MongoNetworkError : connection 0 To 127. 0.0.1 :8080 closed}?

java - 如何使用 cassandra session 进行多线程?

node.js - 创建后如何在 mongoose 中填充子文档?

javascript - 有什么理由不将请求/响应作为参数传递?

node.js - 如何将 HTML 模板转换为 Node.JS Web 应用程序

javascript - 如何在 mysql/express 中使用变量作为列名?

javascript - 在 angular js 应用程序的 tomcat 访问日志中获取 session ID

asp.net - 注销按钮 IIS6 ASP.NET 基本身份验证