3

我正在使用以下模块开发 NodeJ:

表达 4.9.8

快速会话 1.9.3

套接字.io 1.2.1

session.socket.io-express4 0.0.3

我正在尝试使用以下代码从 app.js 中的 session.socket.io-express4 获取会话:

首先是 app.js 中所有东西的初始化:

var server = app.listen(3000, function() {
  debug('Express server listening on port ' + server.address().port);
});

var io = require('socket.io')(server);
var sessionstore = require('sessionstore');
var sessionStore = sessionstore.createSessionStore();
var cookieParserVar = cookieParser('bingo');

app.use(session({
secret: 'bingo',
cookie: {httpOnly: true, secure: true, maxAge: new Date(Date.now() + 3600000)},
store: sessionStore,
resave: true,
saveUninitialized: true
}));

var SessionSockets = require('session.socket.io-express4');
sessionSockets = new SessionSockets(io, sessionStore, cookieParserVar);
require('./models/socket.js')(sessionSockets);

我的socket.js:

function handleSocket(sessionSockets) {
     sessionSockets.on('connection', function (err, socket, session) {
          console.log("session : " + session);
    });
}

module.exports = handleSocket;

问题是会话未定义。有任何想法吗 ?

更新

所以我尝试改用socket.io-sessions。

这是我的代码:

var sessionstore = require('sessionstore');
var sessionStore = sessionstore.createSessionStore();
var cookieParserVar = cookieParser();

app.use(session({
    secret: 'bingo',
    key: 'express.sid',
    store: sessionStore,
    resave: true,
    saveUninitialized: true
}));

io.set("authorization", socketIoSessions({
    key:    'express.sid',       //the cookie where express (or connect) stores its session id.
    secret: 'bingo', //the session secret to parse the cookie
    store:   sessionStore      //the session store that express uses
  }));

require('./models/socket.js')(io);

我的模型/socket.js 文件包括:

function handleSocket(sock) {
        sock.on('connection',function(socket)
        {
                socket.handshake.getSession(function (err, session) {
                        console.log("HERHERHEHREHREHRHEHERHERHRHERHERHEHREHREHREHR");
                        console.log(session);
                        console.log(err);
                });
                require('../commands/echo.js')(sock);
        });
}

module.exports = handleSocket;

这是我得到的错误:

/mnt/storage/home/ufk/work-projects/bingo/server/bingo-server/models/socket.js:8
            socket.handshake.getSession(function (err, session) {
                             ^
TypeError: Object #<Object> has no method 'getSession'
at Namespace.<anonymous> (/mnt/storage/home/ufk/work-projects/bingo/server/bingo-server/models/socket.js:8:34)
at Namespace.emit (events.js:95:17)
at Namespace.emit (/mnt/storage/home/ufk/work-projects/bingo/server/bingo-server/node_modules/socket.io/lib/namespace.js:205:10)
at /mnt/storage/home/ufk/work-projects/bingo/server/bingo-server/node_modules/socket.io/lib/namespace.js:172:14
at process._tickCallback (node.js:419:13)

我错过了什么?

最后更新

socket.io-session 按预期工作。我唯一需要更改的是授权回调,以使其与 socket.io-1.0 兼容,我做了以下操作:

io.use(function (socket, next) {
        var handshakeData = socket.handshake;
        ioSession(cookieParser(config.app.session_key), sessionStore)(handshakeData, next);
    }
);
4

1 回答 1

3

更新

原始答案对问题的解释仍然是所有相关的,但修复更简单(也更安全)。只需使用 socket.io-session 代替。session.socket.io-express4 模块仅在您使用 cookieParser 的连接版本时才需要,该版本没有与较新的 cookie 解析器相同的签名处理。

原始答案

这是由于同时使用 cookie-parser secret 和 express-session secret 时 sesssion.socket.io-express4 中的一个错误。正在发生的事情是 sesssion.socket.io-express4 试图剥离 connect.sid cookie 的签名。你可以在这里看到:

if(handshake.cookies && handshake.cookies[key]) handshake.cookies[key] = (handshake.cookies[key].match(/\:(.*)\./) || []).pop();

签名的 cookie 看起来像这样s:<value>.<signature>,正则表达式选择介于:和之间的任何内容,.这将是签名 cookie 的值。问题是,如果你传入一个秘密,cookie-parser 将删除签名本身。这意味着 session.socket.io-express4 正在期待s:<value>.<signature>但正在接收<value>,因此正则表达式返回未定义。要解决此问题,您可以省略 cookie-parser 中的秘密。

我已向session.socket.io-express4 提交了一个拉取请求,并修复了此错误,因此您必须使用与 express-session 具有相同秘密的 cookie 解析器。

tl;博士

不要向 cookie 解析器提供秘密。以下应该按您的预期工作:

var server = app.listen(3000, function() {
  debug('Express server listening on port ' + server.address().port);
});

var io = require('socket.io')(server);
var sessionstore = require('sessionstore');
var sessionStore = sessionstore.createSessionStore();
var cookieParserVar = cookieParser();

app.use(session({
    secret: 'bingo',
    store: sessionStore,
    resave: true,
    saveUninitialized: true
}));

var SessionSockets = require('session.socket.io-express4');
sessionSockets = new SessionSockets(io, sessionStore, cookieParserVar);
require('./models/socket.js')(sessionSockets);
于 2014-12-11T07:03:59.530 回答