如何获取(Express的)WebSocket连接的sessionID?

16

我正在使用WebSockets,安装了npm install ws,并且与Express在同一个端口上运行。

我想要获取刚刚建立并升级为WebSocket的HTTP连接的相关'sessionID'。

// start express listening
server.listen(conf.server.port, conf.server.host);

var WebSocketServer = require('ws').Server
  , wss = new WebSocketServer({server: server});

wss.on('connection', function(ws) {
    var sessionID = // how do I get this?
    ws.on('message', function(message) {
        console.log('received: %s', message);
    });
    ws.send('something');
});

如何实现这一点?

(我目前通过将sessionID发送到页面来解决此问题,但这很不美观。)

2个回答

16
  1. 解析 cookie
  2. 获取会话 ID
  3. 获取会话数据

var express = require('express');
var parseCookie = express.cookieParser();
var MemoryStore = express.session.MemoryStore;

var store = new MemoryStore();

app.configure(function() {
    app.use(express.session({ store: store, secret: '123456', key: 'sid' }));
});

wss.on('connection', function(ws) {
    parseCookie(ws.upgradeReq, null, function(err) {
        var sessionID = ws.upgradeReq.cookies['sid'];
        store.get(sessionID, function(err, session) {
            // session
        });
    }); 

    ws.on('message', function(message) {
        console.log('received: %s', message);
    });
    ws.send('something');
});

1
这是正确的方向,但没有'sid' cookie。有:connect.sid: n8Pbh5hPhNNC3B6PAkyuaRgv.o9wnmI3fiJ47kJMUfW0xVcMRkhjFkMbgvki/CTtemvUsessionid: 12d2b0c6f3c3eb661215a401d1942122。其中哪一个是会话密钥,另一个是什么? - fadedbee
'connect.sid' 是 Express cookie 的默认键。在上面的代码中,Express 被配置为使用会话键 'sid'... 如果您不自定义它,则键是 'connect.sid'。 - nguyenkha
那个 cookie 不会被签名吗?如果是这样,您将不得不在使用它作为 store.get 的键之前删除已签名的部分。 - UpTheCreek
3
经过一番调试,我成功地让这个变体运行起来了。关键是将密钥放入express.cookieParser('123456')中,并使用upgradeReq.signedCookies['sid'] - Wivlaro
我综合了评论并包含了一个新的代码示例,见下方! - mattdlockyer
在最近的Express版本中,MemorySession的位置也随着中间件的分离而发生了变化:require('express-session').MemoryStore。 - Tosha

7
这真是个噩梦,最终我使用了已签名cookie的方式使它工作起来!
设置您的存储(例如内存存储):
var MemoryStore = express.session.MemoryStore;
store = new MemoryStore();

在应用 / 服务器js文件中像这样将parseCookie公开为全局(如果您需要在其他模块中使用它):
app.use(parseCookie = express.cookieParser('secret'));

现在设置套接字:
//this method gets called later
var ensureAuthenticatedSocket = function(handshake, callback) {
    cookie = cookieParser(handshake, null, function(err) {
        var sessionID = handshake.signedCookies['sid'];
        store.get(sessionID, function(err, session) {
            callback(err, session);
        });
    });
};
//listen time
io = io.listen(server);
//configure authentication
io.configure(function() {
    io.set('authorization', function(handshake, callback) {
        //call the method with handshake as parameter, wait for callback
        ensureAuthenticatedSocket(handshake, function(err, session) {
            if (!err && session) {
                //no error + found session = wicked!
                callback(null, true);
            } else {
                callback(null, false);
            }
        });
    });
});
...
//more socket code

5
目前有关Node的一切都是一场噩梦。所有信息都缺乏非常重要的东西......到处都缺少解释,许多事情被认为是理所当然的。 - vsync
@vsync L2网络应用程序先生。 - AlbertEngelB
我发现它仍然比PHP更好,因为我做了很多前后端项目,所以通用语言对我来说更好。 - mattdlockyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接