Вдохновленный Как делиться сеансами с Socket.IO 1.x и Express 4.x? я реализовал аутентификацию сокета каким-то "чистым" способом, где нет необходимости использовать куки-парсер и читать куки из заголовков, но некоторые моменты остаются для меня неясными . В примере используется последняя стабильная версия 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
приводит к поломке приложения, проблема может быть решена путем предоставления пустого объекта вместо < strong>socket.request.res, например: sessionMiddleware(socket.request, {}, next);
, что мне кажется грязным взломом. По каким причинам socket.request.res уступает undefined
?