Вопрос по node.js, express, session-cookies, javascript, socket.io – Не удается получить экспресс-идентификатор сеанса из файлов cookie с Socket.IO

14

У меня есть типичное веб-приложение в Node, использующее инфраструктуру Express и промежуточное программное обеспечение сеанса. Я также использую Socket.io для определенных динамических частей моего приложения (в настоящее время это механизм чата, но он тангенциальный). Я смог самостоятельно настроить сеансы и socket.io самостоятельно, но хотел бы объединить их (например, связать сообщения чата в сокете с учетными записями пользователей, не обращаясь к базе данных).

Следует отметить (и я вижу, что это является возможной проблемой), я использую два экспресс-сервера на разных портах: один для обычного HTTP-трафика и один для HTTPS-трафика. Тем не менее, у меня оба сервера проходят идентичную конфигурацию и используют одно и то же хранилище сеансов. Сеансы для меня сохраняются между страницами http и https. Сеанс изначально устанавливается через страницу, обслуживаемую из HTTPS, а страница socket.io является обычным HTTP.

Я следую за руководством, расположеннымВот добиться того, что я ищу относительно интеграции socket.io и сессий. Однако внутри функции авторизации data.headers.cookie никогда не устанавливается, несмотря на то, что основанные на сеансе части моего приложения работают должным образом. Что более странно, так это то, что после настройки сеанса яconsole.log(document.cookie) из браузера я получаю пустую строку, но когда я просматриваю свои файлы cookie с помощью панели инструментов разработчика Firefox, появляется файл cookie SID для экспресс и подключения.

Вот соответствующая часть кода сервера:

<code>var config = {
    ip          : "127.0.0.1",
    httpPort    : 2031,
    httpsPort   : 2032
};

var utils       = require("./utils"),
    express     = require('express'),
    fs          = require('fs'),
    parseCookie = require('./node_modules/express/node_modules/connect').utils.parseCookie,
    routes      = require('./routes')(config); 

var httpsOpts = {
    key : fs.readFileSync("cert/server-key.pem").toString(),
    cert: fs.readFileSync("cert/server-cert.pem").toString()
 };

var app             = express.createServer(),
    https           = express.createServer(httpsOpts),
    io              = require("socket.io").listen(app, { log: false}),
    helpers         = require("./helpers.js"),
    session         = new express.session.MemoryStore(),
    sessionConfig   = express.session({
        store   : session,
        secret  : 'secret',
        key     : 'express.sid',
        cookie  : {maxAge : 60 * 60 * 1000}
    }); //share this across http and https

configServer(app);
configServer(https);

//get SID for using sessions with sockets
io.set('authorization', function(data, accept){
    if(data.headers.cookie){
        data.cookie = parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['express.sid'];
    } else {
        return accept("No cookie transmitted", false);
    }

    accept(null, true);
});

io.sockets.on('connection', function(socket){
    //pull out session information in here
});

function configServer(server) {
    server.configure(function(){
        server.dynamicHelpers(helpers.dynamicHelpers);
        server.helpers(helpers.staticHelpers);
        server.set('view options', { layout: false });
        server.set('view engine', 'mustache');
        server.set('views', __dirname + '/views');
        server.register(".mustache", require('stache'));
        server.use(express.static(__dirname + '/public'));
        server.use(express.bodyParser());
        server.use(express.cookieParser());
        server.use(sessionConfig);
    });
}
</code>

А вот соответствующий код на клиенте:

<code><script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        var socket = io.connect('http://127.0.0.1'); //make sure this isn't localhost!
        socket.on('server', function(data){
            //socket logic is here
        });
    }
</script>
</code>

UPDATE

Даже после установки файла cookie вручную (а не только переменной сеанса) в маршруте для страницы, которая использует SocketIO, часть запроса cookie по-прежнему отсутствует.

Ваш Ответ

1   ответ
11

Я никогда бы не подумал об этом, пока не сказал, чтобы посмотреть на инициализацию на стороне клиента. Я изменил адрес с localhost на явный IP-адрес (127.0.0.1), и теперь файлы cookie отправляются с заголовком в Socket.IO. Я не уверен, очевидно ли это или нет, так как я предположил, что localhost в любом случае был сопоставлен с 127.0.0.1.

Да, как уже упоминалось @freakish, всегда используйте минимальный код на стороне клиента:var socket = io.connect()
Точно такая же проблема для меня, и это сработало отлично.
Именно так! Вот почему я хотел получить код клиента. Вы также можете использоватьvar socket = io.connect(); не давая хозяина вообще. Должно сработать.

Похожие вопросы