【发布时间】:2014-06-23 00:38:09
【问题描述】:
我想在我的 socket.io 应用程序中访问 express 4 会话。 我是 Node 的新手,在实现这个功能时遇到了一些麻烦。
我找到了一个允许访问 express 4 会话的 npm 模块:https://www.npmjs.org/package/session.socket.io-express4 或 https://github.com/eiriklv/session.socket.io
如果您查看下面我的 app.js 代码,我在 session、sessionStore 或 cookieParser 设置中做错了,因为我无法让这个模块工作。
// init modules
var express = require('express');
var helmet = require('helmet');
var fs = require('fs');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var memoryStore = session.MemoryStore;
var app = express();
// set variables
var options = {
key: fs.readFileSync('./openssl_keys/server_key.pem'),
cert: fs.readFileSync('./openssl_keys/server_cert.pem')
};
var cookieSecret = "secret phrase";
var sessionStore = new memoryStore();
app.set('env', process.env.NODE_ENV || 'development');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser(cookieSecret));
app.use(session({
secret: cookieSecret,
cookie: {httpOnly: true, secure: true},
store: sessionStore
}));
app.use(function(req, res, next){
res.locals.session = req.session;
next();
});
app.use(express.static(path.join(__dirname, 'public')));
//routes
require('./routes/index')(app);
require('./routes/test')(app);
// starting http and https servers
var http = require('http').createServer(app).listen(8000, function(){
console.log("http server listening on port 8000");
});
var https = require('https').createServer(options, app).listen(8080, function(){
console.log("https server listening on port 8080");
});
// starting socket.io & session handler
var serverIO = require('socket.io').listen(https);
var SessionSockets = require('session.socket.io-express4');
var io = new SessionSockets(serverIO, sessionStore, cookieParser);
io.on('connection', function(err, socket, session){
if(err) throw err;
console.log("connected");
//console.log(session);
socket.on('clientMessage', function(content) {
console.log("received client message")
console.log(content);
});
});
module.exports = app;
我尝试了多种可能性,例如:
- 禁用
https服务器。 - 使用密码短语设置
cookieParser对象(因此它“实际上”将密码短语导出到io = new SessionSockets(serverIO, sessionStore, cookieParser);) - 使用最少的
cookie选项。
无论如何我对此有点迷茫,欢迎任何建议/批评。
更新
好的,经过多次尝试,我想我可以让它工作!
问题在于 cookieParser 初始化,正确的方法似乎是:
var cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(session({
secret: "secret phrase",
cookie: {httpOnly: true, secure: true},
store: sessionStore
}));
var io = new SessionSockets(serverIO, sessionStore, cookieParser());
请注意,如果我使用 var io = new SessionSockets(serverIO, sessionStore, cookieParser);(而不是 cookieParser()),则它不起作用。 这似乎是问题所在。
如果我使用:
app.use(cookieParser("secret phrase"));
app.use(session({
secret: "secret phrase",
cookie: {httpOnly: true, secure: true},
store: sessionStore
}));
var io = new SessionSockets(serverIO, sessionStore, cookieParser("secret phrase"));
然后模块崩溃并显示以下错误消息:
session.socket.io-express4/session.socket.io.js:41
ake.signedCookies[key] = handshake.signedCookies[key].match(/\:(.*)\./).pop();
^
TypeError: Cannot call method 'pop' of null
但如果我使用:
app.use(cookieParser("secret phrase"));
app.use(session({
secret: "secret phrase",
cookie: {httpOnly: true, secure: true},
store: sessionStore
}));
var io = new SessionSockets(serverIO, sessionStore, cookieParser());
然后一切看起来都很好。
现在,在 cookie-parser 文档 (https://github.com/expressjs/cookie-parser) 中,您可以传递一个密钥来对 cookie 进行签名。这是我想要的。
有人可以解释一下 cookie-parser 密码短语和会话密码短语的关系吗?它们必须相同/不同吗?
【问题讨论】:
-
另请参阅此相关答案:stackoverflow.com/a/24859515/1407170
标签: node.js session express socket.io