2012-04-28 14 views
14

Tengo una aplicación web típica en Node que utiliza Express Framework y el middleware de sesión. También estoy usando Socket.io para ciertas partes dinámicas de mi aplicación (actualmente, este es un mecanismo de chat, pero eso es tangencial). Pude configurar las sesiones y socket.io por sí mismos, pero me gustaría combinarlos (por ejemplo, para asociar mensajes de chat con cuentas de usuario sin tocar la base de datos).No se puede obtener la ID de sesión Express de las cookies con Socket.IO

Cabe señalar (y puedo ver que este es un posible punto de problema), estoy ejecutando dos servidores Express en diferentes puertos: uno para el tráfico HTTP regular y otro para el tráfico HTTPS. Sin embargo, estoy haciendo que ambos servidores se sometan a una configuración de identificación y compartan la misma tienda de sesión. Las sesiones persisten para mí entre las páginas http y https. La sesión se está configurando inicialmente a través de una página servida desde HTTPS y la página de socket.io es vainilla HTTP.

Estoy siguiendo la guía ubicada here para lograr lo que estoy buscando con respecto a la integración de socket.io y sesiones. Sin embargo, dentro de la función de autorización, data.headers.cookie nunca se establece, a pesar de que las porciones basadas en la sesión de mi aplicación funcionan como se esperaba. Lo que es más extraño es que después de configurar una sesión, si hago un console.log(document.cookie) desde el navegador, obtengo una cadena vacía, pero cuando miro mis cookies con la barra de herramientas del desarrollador de Firefox, hay una cookie SID para expresar y conectar.

Aquí es la parte relevante del código del servidor:

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); 
    }); 
} 

Y aquí está el código correspondiente en el cliente:

<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> 

ACTUALIZACIÓN

Incluso después de establecer una cookie manualmente (y no solo una variable de sesión) en la ruta de la página que está usando SocketIO, la porción de cookies de la solicitud sigue siendo ausente.

Respuesta

11

Nunca hubiera pensado en esto hasta que me dijeron que mirara la inicialización en el lado del cliente. Cambié la dirección de localhost a la IP explícita (127.0.0.1) y las cookies ahora se están enviando con el encabezado en Socket.IO. No estoy seguro de si esto es obvio o no, ya que asumí que localhost estaba siendo mapeado a 127.0.0.1 de todos modos.

+8

¡Exactamente! Es por eso que quería el código de cliente. También puede usar 'var socket = io.connect();' sin dar ningún host. Deberia trabajar. – freakish

+0

Exacto mismo problema para mí, y esto funcionó perfectamente. – bento

Cuestiones relacionadas