express-session non sta impostando cookie di sessione durante l’utilizzo con socket.io

Sto cercando di implementare l’autenticazione e le sessioni con socket.io.

Dopo un sacco di ricerche 1 , ho impostato quanto segue che si avvale di express ed express session.

Il problema è che, le connessioni express e socket.io sembrano avere sessioni diverse dal momento che l’ id che sto ottenendo è diverso.

Inoltre, nessun cookie è impostato nel browser dalla mia applicazione (che è probabilmente il motivo per cui entrambi i componenti creano sessioni diverse?)

Sto usando express express 4.13.3 1.12.1 e socket.io 1.3.7 .

    Di seguito è riportato il codice lato server che ho impostato:

     var app = require('express')(); var server = app.listen(80); var parser = require('body-parser'); var Session = require('express-session'); var io = require('socket.io')(server); var game = require('./game.js'); var session = Session({ secret: 'some secret', resave: false, saveUninitialized: false, cookie: { 'name': 'test', httpOnly: false, secure: false, maxAge: ((60 * 1000) * 60) } }); app.use(parser.urlencoded({ extended: false })); app.use(session); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.post('/login', function(req, res) { console.log('login %s', req.session.id); console.dir(req.session, { color: true }); res.json({ status: 'success' }); }); io.use(function(socket, next) { session(socket.handshake, {}, next); }); console.log('socket server started @ %s !', 80); io.on('connection', function(socket) { console.log('user connected %s', socket.handshake.session.id); console.dir(socket.handshake.session, { color: true }); socket.on('disconnect', function() { console.log('user disconnected'); console.dir(socket.handshake.session, { color: true }); }); }); 

    e il codice al client per scopi di test:

     $.ajax({ url: 'http://127.0.0.1:80/login', type:'post', success: function(response) { var socket = io('http://127.0.0.1:80'); } }); 

    Di seguito è riportato l’output in console:

    inserisci la descrizione dell'immagine qui

    e questa è la sezione delle risorse nel browser:

    inserisci la descrizione dell'immagine qui

    Sono persino confuso vedendo che l’object della session non ha alcuna proprietà id quando si accede alla console, ma session.id stampa valori diversi. Forse questo proviene dalla catena del prototipo di oggetti o qualcosa del genere.

    L’unica differenza che posso pensare con il mio codice e le esercitazioni là fuori è che stanno tutti servendo la pagina index.html dallo stesso server express. Nel mio caso ho il file localmente.

    Ho letto da qualche parte che in questi casi devo inviare una richiesta http per esprimere prima di stabilire la connessione socket.io.

    La libreria laterale del client socket.io.js viene servita dallo stesso server condiviso da express e socket.io ( ), oltre a questo sto anche premendo il percorso express /login per testare lo scopo prima che venga stabilita la connessione socket.

    Quindi mi chiedo perché nessun cookie viene impostato sul lato client e perché le richieste express e socket hanno creato sessioni diverse …? Cosa mi manca qui ..?


    1 Il codice si basa principalmente su:

    • Come condividere sessioni con Socket.IO 1.xe Express 4.x?
    • socket.io e sessione?

    PS: Quello che sto cercando di fare è, quando un client socket si ricollega, ho bisogno di riportarlo dove era con i dettagli della sessione. Non voglio davvero condividere le sessioni con Express, ma il middleware express è l’unico modo in cui mi sono imbattuto per implementare le sessioni con socket.io.

    Il problema non aveva nulla a che fare con express o socket.io.

    Il problema è che stavo caricando il progetto da un server locale diverso dal server express e socket.io.

    Quindi è una richiesta di ajax interdominio, nel qual caso alcuni browser si rifiutano di gestire l’intestazione Set-Cookie .

    Possiamo aggiustarlo aggiungendo

     xhrFields: { withCredentials: true }, 

    nelle opzioni Ajax come menzionato in questa risposta

    O se stai lavorando con angular, {withCredentials: true} inviato {withCredentials: true} come

    $http({withCredentials: true, ...}).get(...) come menzionato in questa risposta .

    Sul lato server, imposta questa intestazione:

     res.header("Access-Control-Allow-Credentials", 'true'); 

    Se lo aggiungi, Chrome non ti consentirà più di utilizzare il carattere jolly * nell’intestazione Access-Control-Allow-Origin .

    Dovresti anche impostarlo su specifici domini consentiti.

     res.header("Access-Control-Allow-Origin", "allowed domains"); 

    Non dovresti

     res.session.save(); // add this line res.json({ status: 'success' }); // or just res.send({status:success}); 

    ?

    Inoltre, ti consiglio di utilizzare il modulo passport-local strategia passport-local per questo scopo, quindi non devi preoccuparti del perché le tue sessioni non funzionino. Una volta mi ha risparmiato un sacco di tempo.