Come funzionano le sessioni in Express.js con Node.js?


96

Utilizzando Express.js , le sessioni sono semplicissime. Sono curioso di sapere come funzionano effettivamente.

Memorizza alcuni cookie sul client? In tal caso, dove posso trovare quel cookie? Se richiesto, come lo decodifico?

Fondamentalmente voglio essere in grado di vedere se un utente ha effettuato l'accesso, anche quando l'utente non è effettivamente sul sito in quel momento (come il modo in cui Facebook sa che hai effettuato l'accesso quando sei su altri siti). Ma suppongo di capire che dovrei prima capire come funzionano le sessioni.

Risposte:


43

Non ho mai usato Express.js, anche se secondo la loro documentazione sull'argomento suona come:

  • I cookie sono memorizzati sul client, con una chiave (che il server utilizzerà per recuperare i dati della sessione) e un hash (che il server utilizzerà per assicurarsi che i dati del cookie non siano stati manomessi, quindi se provi a cambiare un valore il cookie non sarà valido)

  • I dati della sessione, al contrario di alcuni framework (ad esempio Play Framework !), Sono conservati sul server, quindi il cookie è più simile a un segnaposto per la sessione che a un titolare dei dati di sessione effettivi.

  • Da qui , sembra che i dati di questa sessione sul server siano conservati in memoria per impostazione predefinita, sebbene potrebbero essere modificati in qualsiasi forma di archiviazione che implementa l'API appropriata.

Quindi, se vuoi controllare le cose senza un reqoggetto di richiesta specifico , come hai detto, devi solo accedere allo stesso archivio. Nella parte inferiore della prima pagina della documentazione, descrive i metodi richiesti che l'archiviazione deve implementare, quindi se hai familiarità con la tua API di archiviazione, forse potresti eseguire un .getAll()se qualcosa del genere esiste, e scorrere i dati della sessione e leggere qualsiasi cosa valori che desideri.


166

Panoramica

Express.js utilizza un cookie per memorizzare un ID di sessione (con una firma di crittografia) nel browser dell'utente e quindi, nelle richieste successive, utilizza il valore di quel cookie per recuperare le informazioni di sessione memorizzate sul server. Questo archivio lato server può essere un archivio di memoria (predefinito) o qualsiasi altro archivio che implementa i metodi richiesti (come connect-redis ).

Dettagli

Express.js / Connect crea una stringa Base64 di 24 caratteri utilizzando utils.uid(24)e la memorizza in req.sessionID. Questa stringa viene quindi utilizzata come valore in un cookie.

Dalla parte del cliente

I cookie firmati vengono sempre utilizzati per le sessioni, quindi il valore del cookie avrà il seguente formato.

[sid].[signature]

Dove [sid] è l'ID sessione e [firma] viene generata firmando [sid] utilizzando la chiave segreta fornita durante l'inizializzazione del middleware della sessione. La fase di firma viene eseguita per evitare manomissioni. Dovrebbe essere computazionalmente impossibile modificare [sid] e quindi ricreare [firma] senza conoscere la chiave segreta utilizzata. Il cookie di sessione è ancora vulnerabile al furto e al riutilizzo, se non è richiesta alcuna modifica di [sid].

Il nome di questo cookie è

connect.sid

Lato server

Se un gestore si verifica dopo il cookieParsere sessionmiddleware, avrà accesso alla variabile req.cookies. Contiene un oggetto JSON le cui chiavi sono le chiavi dei cookie ei valori sono i valori dei cookie. Questo conterrà una chiave denominata connect.side il suo valore sarà l'identificatore di sessione firmato.

Ecco un esempio di come impostare un percorso che verificherà l'esistenza del cookie di sessione ad ogni richiesta e ne stamperà il valore sulla console.

app.get("/*", function(req, res, next) {

    if(typeof req.cookies['connect.sid'] !== 'undefined') {
        console.log(req.cookies['connect.sid']);
    }

    next(); // Call the next middleware
});

Dovrai anche assicurarti che il router ( app.use(app.router)) sia incluso dopo cookieParsere sessionnella sezione di configurazione.

Di seguito è riportato un esempio dei dati archiviati internamente da Express.js / Connect.

{
  "lastAccess": 1343846924959,
  "cookie": {
    "originalMaxAge": 172800000,
    "expires": "2012-08-03T18:48:45.144Z",
    "httpOnly": true,
    "path": "/"
  },
  "user": { 
    "name":"waylon",
    "status":"pro"
  }
}

Il usercampo è personalizzato. Tutto il resto fa parte della gestione della sessione.

L'esempio è tratto da Express 2.5.


1
quando si stampa il valore del cookie con console.log, fornisce il cookie codificato (firmato). come ottengo le informazioni reali?
vsync

Cosa intendi con - "Il cookie di sessione è ancora vulnerabile al furto e al riutilizzo, se non è richiesta alcuna modifica di [sid]."? dato che SID è generato da express, non possiamo mai cambiarlo, giusto?
Hrushikesh

2
@WebHrushi stavo pensando a un attacco Man-in-the-Middle: en.wikipedia.org/wiki/Man-in-the-middle_attack
Waylon Flinn

Può qualcuno aiutarlo con questa domanda: stackoverflow.com/questions/21982791/...
RoundRobin

come creo un token per un particolare session_id?
aman verma

9

Sono curioso di sapere come funzionano effettivamente.

Prova a guardare questa risposta e le cose wiki .

Memorizza alcuni cookie sul client?

Sì, di solito è un cookie con un ID di sessione assegnato, che deve essere firmato con un segreto per evitare falsificazioni.

In tal caso, dove posso trovare quel cookie? Se richiesto, come lo decodifico?

Non dovresti scherzare con un cookie di sessione sul lato client. Se vuoi lavorare con le sessioni sul lato server dovresti controllare express.js correlato e connettere i documenti.


Signore, possiamo parlare? Ho dei dubbi riguardo a tutto questo.
Suraj Jain

0

Oltre alle già ottime risposte, ecco 2 diagrammi che ho creato per spiegare le sessioni Express, il loro collegamento con i cookie e il negozio:

  • biscotto al cioccolato: cioccolato
  • biscotto alla fragola: fragola
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.