Вдохновленный Как обмениваться сеансами с 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
middlewares?) В некотором роде я ожидал этого app.use(sessionMiddleware);, чтобы запустить этот первоначальный запрос, а затем легко получить доступ к socket.request.session
Во-вторых, каковы сценарии, в которых будут срабатывать middlewares, определенные с помощью io.use()
? Только для первоначального запроса на квитирование HTTP? Похоже, что io.use()
используется для сокетов 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
?