灵感来自如何与 Socket.IO 1.x 和 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访问该初始请求。
我的第一个问题是为什么握手请求不在快速会话中间件的范围内?(更一般地在app.use
中间件的范围内?)在某种程度上我期望这个app.use(sessionMiddleware); 在初始请求之前触发,然后轻松访问socket.request.session
其次,用 定义的中间件io.use()
会触发的场景是什么?仅适用于初始 HTTP 握手请求?似乎io.use()
用于与套接字相关的东西(问题是:什么东西),而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
?