I've recently asked this question on SO. As the question was not answered yet, I've come up with an approach. But I wanted to check if there is not any security flaw in this solution.
Domanda
Avevo scritto un plugin per la gestione delle sessioni in node.js per il framework web Muneem. Ecco lo pseudo codice per creare una nuova sessione;
function createSession(){
// read encrypted session-id from the request
if( sessionId ){
// decrypt it
if (decryptedSessionId ) {
//read session detail from the store
options.store.get(decryptedSessionId, (err, sessionFromStore) => {
if(err){
throw Error(err);
}else if( sessionFromStore){
if( shouldRenew(sessionFromStore) ){
//delete previous session
options.store.destroy(sessionFromStore.id, err=> {
//update the session object in memory
});
}
}else{ //session detail is not present in store
// create new session
}
});
} else { //invalid or tempered session
// throw error
}
}else{ //session-id is not presnet in request
// create new session
}
}
Come puoi notare, sto rinnovando una sessione quando è valida e soddisfo determinate condizioni eliminando la sessione precedente. Ma non lo aggiorno immediatamente nel negozio. Al contrario, aggiorno le informazioni sulla sessione nel negozio e imposto i cookie quando la risposta viene inviata al client.
Supponiamo ora una condizione, quando il server riceve più richieste con lo stesso ID sessione che è idoneo a rinnovare. Rinnovo la sessione alla prima richiesta.
Scenari
- La sessione non viene aggiornata nell'archivio. Così rinnoverò la sessione precedente con un altro nuovo ID di sessione. In questo caso, un utente avrà l'ID sessione multipli.
- La sessione viene aggiornata nello store. Ora, la sessione precedente non sarà disponibile nel negozio. Dovrò chiedere all'utente di effettuare nuovamente il login se è una sessione autorizzata. O creerò un'altra sessione.
Soluzione
Per risolvere questa condizione di gara, stavo pensando di creare una tabella DB in cui i record possono scadere automaticamente dopo una durata fissa, ad esempio tempo di transizione. Quando una sessione deve essere rinnovata, facciamo una voce nella tabella sessione scaduta con il vecchio e il nuovo ID di sessione. Il resto delle operazioni è lo stesso di pseudo codice sopra. Ora, se la prossima richiesta con id di sessione scaduta raggiunge il server entro il tempo di transizione, diciamo 10 secondi, quindi recupereremo il nuovo id di sessione e continueremo la sessione.
Qui è il codice completo, nel caso avessimo bisogno.