Node.js + Express.js (Connect) - 从“升级”访问会话事件

发布于 2024-11-28 23:02:26 字数 1075 浏览 1 评论 0原文

我正在尝试使用 Express.js 框架从 Node.js 服务器触发的“升级”事件访问会话对象。我已正确设置会话支持,并且可以从标准 .get .post .put 和 .delete 方法访问它,例如。

app.get('/', function(req, res) {
    req.session.test = 'Hello world'; // Works fine
    res.render('index');
});

但是,如果我像这样在服务器上连接“升级”事件:

app.on('upgrade', function(req, socket) {
    var message = req.session.test; // Doesn't work
});

我无法访问会话对象。据我所知,Connect Session 中间件仅连接 get/post/put/delete 方法的会话,而不连接“升级”等自定义事件。

仅供参考,在 WebSocket 握手期间客户端发出“升级”事件,我尝试从初始 WebSocket 握手访问会话。在握手期间,会话 cookie 肯定存在于 HTTP 标头中,例如:

app.on('upgrade', function(req, socket) {
    var cookieHeader = req.headers['cookie'];
    console.log(cookieHeader);
});

...将输出 Connect 会话 cookie。是否有一种方法可以使用原始会话 cookie 令牌手动构建会话对象?


更新:在node.js IRC聊天室与一些人交谈过,显然这要么非常困难,要么不可能。 Connect 中间件不会暴露于自定义/异常事件,例如“升级”。他们说要在 Github 上提出问题,所以这里是:

https://github.com/senchalabs /连接/问题/342

I'm trying to access the session object from an 'upgrade' event fired by a Node.js server using the Express.js framework. I have set up Session support correctly and can access it from the standard .get .post .put and .delete methods eg.

app.get('/', function(req, res) {
    req.session.test = 'Hello world'; // Works fine
    res.render('index');
});

But if I hook up an on 'upgrade' event on the server like so:

app.on('upgrade', function(req, socket) {
    var message = req.session.test; // Doesn't work
});

I can't access the session object. As far as I'm aware, the Connect Session middleware only hooks up the session for the get/post/put/delete methods, but not for custom events such as 'upgrade'.

FYI, an 'upgrade' event is issued from a client during a WebSocket handshake, I'm trying to access the session from the initial WebSocket handshake. The session cookie is definitely there in the HTTP headers during the handshake eg:

app.on('upgrade', function(req, socket) {
    var cookieHeader = req.headers['cookie'];
    console.log(cookieHeader);
});

...will output the Connect session cookie. Is there perhaps a way to build up the session object manually using the raw session cookie token?


Update: Been speaking to to some people on the node.js IRC chatroom, apparently this is either very difficalt or impossible. The Connect middleware isn't exposed to custom/unusual events such as 'upgrade'. They said to raise an issue in Github, so here it is:

https://github.com/senchalabs/connect/issues/342

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

-小熊_ 2024-12-05 23:02:26

由于您无权访问响应对象,因此您应该能够通过获取会话存储并使用从 cookie 获取的 session_id 调用 get(session_id, callback) 来查找会话对象。如果您拥有的 req 对象通过 req.res 链接到响应,那么您也可以实际调用普通会话中间件函数,express.js 会这样做你,但如果这是一个原始的 node.js 事件,那么此时可能尚未建立该连接。创建中间件时,您必须手动创建会话 Store 实例并保留对其的引用,然后将其传递给 options 对象中的会话中间件工厂函数。

Since you don't have access to the response object, you should be able to look up the session object by getting the session store and calling get(session_id, callback) with the session_id you get from the cookie. You also may be able to actually call the normal session middleware function if the req object you have is linked to the response via req.res, which express.js will do for you, but if this is a raw node.js event, then that connection might not have been made at this point. When you create the middleware, you'll have to create the session Store instance manually and keep a reference to it, then pass it to the session middleware factory function in the options object.

谁的新欢旧爱 2024-12-05 23:02:26

如果您使用的是快速会话,这应该会有所帮助:

import session from 'express-session'
import express from 'express'

import http from 'http'
import { WebSocketServer } from 'ws'

// Declare an Express app 
const app = express()

// Declare an HTTP server for the app
const server = http.createServer(app)

// Initialize *express-session* and use it as a middleware
const sessionHandler = session({
  saveUninitialized: false,
  secret: 'my little secret',
  resave: false
})
app.use(sessionHandler)

// Define a builder for message handler with WebSocket and Session as context 
const onMessage = (ws, session) => (message) => {
    // create a handler for message given the ws and session
}

// Create a *WebSocketServer* without an attached HTTP server
const wsServer = new WebSocketServer({ noServer: true })

// define what to do on a 'connection' event
wsServer.on('connection', (ws, session) => {
  ws.on('message', onMessage(ws, session))
})

// 'upgrade' event comes when the browser ask for a WebSocket
server.on('upgrade', (req, socket, head) => {
  // we call the *sessionHandler* to retrieve/create the session 
  sessionHandler(req, {}, () => {
    // ask the *WebSocketServer* to manage the upgrade
    wsServer.handleUpgrade(req, socket, head, (ws) => {
      console.log(req.session)
      // emit a 'connection' event (handler above) with the create WebSocket and current session
      wsServer.emit('connection', ws, req.session)
    })
  })
})

If you are using express-session, this should help :

import session from 'express-session'
import express from 'express'

import http from 'http'
import { WebSocketServer } from 'ws'

// Declare an Express app 
const app = express()

// Declare an HTTP server for the app
const server = http.createServer(app)

// Initialize *express-session* and use it as a middleware
const sessionHandler = session({
  saveUninitialized: false,
  secret: 'my little secret',
  resave: false
})
app.use(sessionHandler)

// Define a builder for message handler with WebSocket and Session as context 
const onMessage = (ws, session) => (message) => {
    // create a handler for message given the ws and session
}

// Create a *WebSocketServer* without an attached HTTP server
const wsServer = new WebSocketServer({ noServer: true })

// define what to do on a 'connection' event
wsServer.on('connection', (ws, session) => {
  ws.on('message', onMessage(ws, session))
})

// 'upgrade' event comes when the browser ask for a WebSocket
server.on('upgrade', (req, socket, head) => {
  // we call the *sessionHandler* to retrieve/create the session 
  sessionHandler(req, {}, () => {
    // ask the *WebSocketServer* to manage the upgrade
    wsServer.handleUpgrade(req, socket, head, (ws) => {
      console.log(req.session)
      // emit a 'connection' event (handler above) with the create WebSocket and current session
      wsServer.emit('connection', ws, req.session)
    })
  })
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文