javascript validate Le migliori pratiche per invalidare JWT cambiando password e logout in node.js?




validate jwt nodejs (4)

Mi piacerebbe conoscere le migliori pratiche per invalidare JWT senza colpire db durante la modifica della password / logout.

Ho l'idea di seguito per gestire più di 2 casi colpendo il database degli utenti.

1.In caso di modifica della password, controllo la password (con hash) memorizzata nell'utente db.

2.In caso di logout, salvo il tempo di ultimo logout nel db dell'utente, quindi confrontando il tempo di creazione del token e il tempo di disconnessione, posso invalidare questo caso.

Ma questi 2 casi hanno il costo di colpire l'utente db ogni volta che l'utente raggiunge l'api. Ogni buona pratica è apprezzata.

AGGIORNAMENTO: Non penso che saremo in grado di invalidare JWT senza colpire db. Quindi ho trovato una soluzione. Ho pubblicato la mia risposta, se avete qualche preoccupazione, siete i benvenuti.


Non c'è modo che io sappia per invalidare arbitrariamente un token senza coinvolgere un database in un modo o nell'altro.

Fai attenzione con Approach 2 se il tuo servizio è accessibile su diversi dispositivi. Considera il seguente scenario ...

  • L'utente effettua l'accesso con iPad, il token 1 emesso e memorizzato.
  • L'utente accede al sito Web. Token 2 rilasciato. L'utente si disconnette.
  • L'utente tenta di utilizzare l'iPad, il token 1 è stato rilasciato prima che l'utente si disconnettesse dal sito Web, il token 1 ora considerato non valido.

Potresti voler considerare l'idea di token di aggiornamento anche se questi richiedono anche l'archiviazione del database.

Vedi anche here per una buona discussione SO riguardo ad un problema simile, in particolare la soluzione di IanB che salverebbe alcune chiamate db.

Soluzione proposta Personalmente, questo è il modo in cui mi approcciare ... l'utente autentica, emesso con token di accesso con una breve scadenza (diciamo 15 minuti) e un token di aggiornamento valido per un periodo molto più lungo o indefinito. Memorizza un record di questo token di aggiornamento in un db.

Ogni volta che l'utente è "attivo", rilascia ogni volta un nuovo token di autorizzazione (valido per 15 minuti ogni volta). Se l'utente non è attivo per oltre 15 minuti e quindi effettua una richiesta (quindi utilizza un jwt scaduto), controlla la validità del token di aggiornamento. Se è valido (incluso il controllo db), emettere un nuovo token di autenticazione.

Se un utente "si disconnette" su un dispositivo o attraverso un sito Web, distrugge entrambi i token di accesso e rinnova la validità del token di aggiornamento utilizzato. Se un utente modifica la propria password su qualsiasi dispositivo, revoca tutti i token di aggiornamento forzandoli ad accedere nuovamente non appena il loro token di accesso scade. Questo lascia una "finestra di incertezza" ma ciò è inevitabile senza colpire un db ogni volta.

L'utilizzo di questo approccio apre inoltre la possibilità agli utenti di poter "revocare" l'accesso a dispositivi specifici, se necessario, come visto con molte delle principali app web.


Non sono sicuro che manchi qualcosa qui, ma trovo che la risposta accettata sia più complicata del necessario.

Vedo che db deve essere colpito per convalidare o invalidare un token per ogni richiesta API, tuttavia il processo totale avrebbe potuto essere più semplice come vedo le cose qui.

Ogni volta che viene creato un jwt, ad esempio durante il login o cambia / ripristina la password, inserisci il jwt con userid in una tabella e mantieni un jti (un numero uuid fondamentalmente) per ogni jwt. Lo stesso jti va anche in payload jwt. In effetti, jti identifica univocamente un jwt. Un utente può avere più jwts allo stesso tempo quando si accede all'account da più dispositivi o browser, nel qual caso, jti differenzia il dispositivo o lo user-agent.

Quindi lo schema della tabella sarebbe, jti | ID utente. (e una chiave primaria del corso)

Per ogni api, controlla se il jti è nella tabella, il che significa che il jwt è valido.

Quando l'utente modifica o reimposta la password, elimina tutto il jti di tale ID utente dal db. Crea e inserisci un nuovo jwt con un nuovo jti nella tabella. Ciò invaliderà tutte le sessioni da tutti gli altri dispositivi e browser eccetto quello che ha cambiato o reimpostato la password.

Quando l'utente esegue il logout, elimina quel particolare jti di quell'utente ma non tutti. Ci sarebbe un singolo accesso ma non un singolo logout. Quindi, quando l'utente si disconnette, non dovrebbe essere disconnesso da tutti i dispositivi. Tuttavia, l'eliminazione di tutti i jtis si disconnetterebbe da tutti i dispositivi.

Quindi sarebbe una tabella e nessun confronto di date. Inoltre sarebbe lo stesso caso se un token di aggiornamento viene utilizzato o meno.

Tuttavia, per ridurre al minimo l'interferenza del db e possibili ritardi, l'utilizzo della cache potrebbe certamente aiutare a semplificare le operazioni sul fronte del tempo di elaborazione.

Nota: si prega di ragionare se si è fuori voto.


Se un utente sta cambiando la sua password, stai andando a colpire il db lì. Ma non vuoi colpire il db per l'autorizzazione?

Ho trovato i vantaggi dell'archiviazione di una stringa per utente e una stringa condivisa globale condivisa insieme ci offre la massima flessibilità con la nostra implementazione JWT. In questo caso particolare memorizzerei un hash della password da usare con la stringa globale e li ho cancellati insieme per un segreto JWT.


Quando viene utilizzato il token di aggiornamento:

1. Cambiando la password: quando l'utente cambia la sua password, nota il tempo della password di modifica nel db dell'utente, quindi quando il tempo della password di modifica è maggiore del tempo di creazione del token, il token non è valido. Quindi la sessione rimanente verrà presto disconnessa.

2. Quando l'utente si disconnette: quando l'utente si disconnette, salva il token in un DB separato (ad esempio InvalidTokenDB e rimuovi il token da Db alla scadenza del token). Quindi l'utente si disconnette dal rispettivo dispositivo, le sue sessioni in altri dispositivi non vengono disturbate.

Quindi, mentre invalida un JWT, seguo i seguenti passaggi:

  1. Controlla se il token è valido o meno.
  2. Se valido, verificare che sia presente in invalidTokenDB (un database in cui i token registrati vengono archiviati fino alla loro scadenza).
  3. Se non è presente, controllare l'ora di creazione del token e il tempo della password modificata nel db dell'utente.
  4. Se è stata modificata la durata della password <tempo di creazione del token, il token è valido.

Preoccupazione per il metodo di cui sopra :

  1. Per ogni richiesta API, ho bisogno di seguire tutti i passaggi precedenti, che potrebbero influire sulle prestazioni.

Quando viene utilizzato il token di aggiornamento: con scadenza del token di accesso come 1 giorno, il token di aggiornamento è valido per la durata

1. Durante la modifica della password: quando l'utente cambia la sua password, modifica il token di aggiornamento dell'utente. Quindi la sessione rimanente verrà presto disconnessa.

2. Quando l'utente si disconnette : quando l'utente si disconnette, salva il token in un DB separato (ad esempio InvalidTokenDB e rimuovi il token da Db alla scadenza del token). Quindi l'utente si disconnette dal rispettivo dispositivo, le sue sessioni in altri dispositivi non vengono disturbate.

Quindi, mentre invalida un JWT, seguo i seguenti passaggi:

  1. controlla se il token è valido o meno
  2. Se valido, controlla se il token è presente in InvalidTokenDB.
  3. Se non è presente, controllare il token di aggiornamento con il token di aggiornamento in userDB.
  4. Se uguale, è un token valido

Preoccupazione per il metodo di cui sopra :

  1. Per ogni richiesta API, ho bisogno di seguire tutti i passaggi precedenti, che potrebbero influire sulle prestazioni.
  2. Come faccio a invalidare il token di aggiornamento, poiché il token di aggiornamento non ha validità, se è utilizzato da un hacker, l'autenticazione è valida, la richiesta sarà sempre positiva.

Nota : Sebbene Hanz abbia suggerito un modo per proteggere il token di aggiornamento in Uso del token di rifacimento nell'autenticazione basata su token è protetto? , Non potrei capire quello che sta dicendo. Qualsiasi aiuto è apprezzato.

Quindi, se qualcuno ha un buon suggerimento, i tuoi commenti sono ben accetti.

AGGIORNAMENTO: sto aggiungendo la risposta nel caso in cui la tua app non abbia bisogno di token di aggiornamento con scadenza a vita. Questa risposta è stata data da Sudhanshu ( https://.com/users/4062630/sudhanshu-gaur ). Grazie Sudhanshu. Quindi credo che questo sia il modo migliore per farlo,

Quando non è necessario token di aggiornamento e nessuna scadenza di token di accesso:

quando l'utente effettua il login, crea un token di accesso nel suo database utente senza tempo di scadenza.

Quindi, mentre si annulla una JWT, seguire i passaggi seguenti,

  1. recuperare le informazioni dell'utente e controllare se il token è nel suo database degli utenti. Se così lo consente.
  2. Quando l'utente si disconnette, rimuovi solo questo token dal suo database utente.
  3. Quando l'utente cambia la sua password, rimuovi tutti i token dal suo database utente e chiedigli di accedere nuovamente.

Pertanto, con questo approccio, non è necessario memorizzare né i token di logout nel database fino alla loro scadenza né memorizzare il tempo di creazione del token durante la modifica della password che era necessaria nei casi di cui sopra. Tuttavia, ritengo che questo approccio sia valido solo se la tua app ha requisiti senza bisogno di token di aggiornamento e nessuna scadenza dei token.

Se qualcuno ha interesse con questo approccio, per favore fatemelo sapere. I tuoi commenti sono benvenuti :)







auth-token