【发布时间】:2015-12-06 02:02:20
【问题描述】:
受How to share sessions with Socket.IO 1.x and Express 4.x? 的启发,我以某种“干净”的方式实现了套接字身份验证,无需使用 cookie 解析器并从标头读取 cookie,但我仍不清楚几项。示例使用最后一个稳定的 socket.io 版本 1.3.6。
var express = require('express'),
session = require('express-session'),
RedisStore = require('connect-redis')(session),
sessionStore = new RedisStore(),
io = require('socket.io').listen(server);
var sessionMiddleware = session({
store : sessionStore,
secret : "blabla",
cookie : { ... }
});
function socketAuthentication(socket, next) {
var sessionID = socket.request.sessionID;
sessionStore.get(sessionID, function(err, session) {
if(err) { return next(err); }
if(typeof session === "undefined") {
return next( new Error('Session cannot be found') );
}
console.log('Socket authenticated successfully');
next();
});
}
io.of('/abc').use(socketAuthentication).on('connection', function(socket) {
// setup events and stuff
});
io.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
app.use(sessionMiddleware);
app.get('/', function(req, res) { res.render('index'); });
server.listen(8080);
index.html
<body>
...
<script src="socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:8080/abc');
</script>
</body>
因此,来自客户端的io('http://localhost:8080/abc'); 将向服务器发送初始 HTTP 握手请求,服务器可以从中收集 cookie 和许多其他请求信息。因此服务器可以通过 socket.request 访问该初始请求。
我的第一个问题是为什么握手请求不在 express-session 中间件的范围内?(更一般地在 app.use 中间件的范围内?)在某种程度上我期望这个 app.use(sessionMiddleware); 在初始请求之前触发,然后轻松访问 socket.request.session
第二,io.use()定义的中间件会在哪些场景下触发?仅适用于初始 HTTP 握手请求?似乎io.use() 用于与套接字相关的stuff(问题是:什么stuff),而app.use 用于标准请求。
我不太清楚为什么在上面的例子中io.use() 在io.of('/abc').use() 之前被触发。我故意写了这个命令,把io.of('/abc').use()放在第一位,看看它是否有效并且有效。
应该反过来写。
最后,socket.request.res也像链接问题中的一些人指出的那样,有时是undefined导致应用程序崩溃,可以通过提供解决问题空对象而不是 socket.request.res,例如:sessionMiddleware(socket.request, {}, next); 在我看来这像是一个肮脏的黑客。 socket.request.res 屈服于undefined 的原因是什么?
【问题讨论】:
标签: javascript node.js express socket.io express-session