2012-04-28 3 views
14

Ich habe eine typische Webanwendung in Node, die das Express-Framework und die Sitzungs-Middleware verwendet. Ich verwende Socket.io auch für bestimmte dynamische Teile meiner Anwendung (derzeit ist dies ein Chat-Mechanismus, aber das ist tangential). Ich konnte Sitzungen und socket.io erfolgreich selbst aufbauen, würde sie aber gerne kombinieren (ZB: Socket-Chat-Nachrichten mit Benutzerkonten verknüpfen, ohne die Datenbank zu treffen).Ich kann keine Express-Sitzungs-ID von Cookies erhalten w/Socket.IO

Es sollte angemerkt werden (und ich kann sehen, dies ist ein möglicher Problempunkt), ich bin zwei Express-Server auf verschiedenen Ports laufen: eine für regelmäßigen HTTP-Verkehr und eine für HTTPS-Verkehr. Ich lasse jedoch beide Server einer identischen Konfiguration unterziehen und den gleichen Sitzungsspeicher teilen. Sitzungen bestehen für mich zwischen HTTP- und HTTPSeiten. Die Sitzung wird zunächst über eine Seite eingerichtet, die von HTTPS bereitgestellt wird, und die Seite socket.io ist Vanilla HTTP.

Ich folge dem Leitfaden here, um zu erreichen, was ich für die Integration von socket.io und Sitzungen suchen. In der Autorisierungsfunktion wird data.headers.cookie jedoch nie festgelegt, obwohl die sitzungsbasierten Teile meiner Anwendung wie erwartet funktionieren. Noch seltsamer ist, dass ich nach dem Setzen einer Sitzung, wenn ich eine console.log(document.cookie) aus dem Browser mache, eine leere Zeichenfolge bekomme, aber wenn ich meine Cookies mit der Firefox-Entwickler-Toolbar ansehe, gibt es ein SID-Cookie für Express und Connect.

Hier ist der relevante Teil des Server-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); 
    }); 
} 

Und hier ist der entsprechende Code auf dem Client:

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

UPDATE

Auch nach einem Cookie manuell einstellen (und nicht nur eine Sitzungsvariable) in der Route für die Seite, die SocketIO verwendet, der Cookie-Teil der Anfrage ist immer noch abwesend.

Antwort

11

Ich hätte nie daran gedacht, bis die Initialisierung auf der Client-Seite zu sehen. Ich habe die Adresse von localhost auf die explizite IP (127.0.0.1) geändert und die Cookies werden nun mit dem Header in Socket.IO gesendet. Ich bin mir nicht sicher, ob das offensichtlich ist oder nicht, da ich annahm, dass localhost sowieso auf 127.0.0.1 abgebildet wurde.

+8

Genau! Deshalb wollte ich den Client-Code. Sie können auch 'var socket = io.connect();' verwenden, ohne einen Host anzugeben. Sollte arbeiten. – freakish

+0

Genau dasselbe Problem für mich, und das hat perfekt funktioniert. – bento

Verwandte Themen