Questa è un'altra domanda "Come è stata dimenticata la mia password?". Tuttavia, affronta esplicitamente due opzioni di implementazione che ho incontrato di recente.
Gli approcci comuni [1,2] che conosco sono basati su un token casuale che può essere utilizzato solo una volta e che ha una validità limitata:
- Visite degli utenti nella pagina delle password dimenticate
- L'utente fornisce l'indirizzo email (o simile)
- Se l'email è associata a un account utente valido
- L'app genera un token unico e casuale t. t è di sufficiente entropia (diciamo 128 bit).
- L'app memorizza il token casuale t e il timestamp creato con l'utente nel database
- L'app invia un'email contenente un link per la reimpostazione della password all'indirizzo email dell'utente. Il link ha un aspetto simile al seguente: link
- L'utente fa clic sul link nell'email
- L'app controlla
- se c'è un token all'interno del database per un dato utente
- se sì, verifica che sia ancora valido in base al timestamp memorizzato
- se sì, consente all'utente di accedere alla pagina resetPassword
- L'utente imposta una nuova password
- Successivamente, l'app invalida il token t
Puoi aggiungere un po 'più di sicurezza come canali fuori banda o domande di sicurezza. Ma per me, questa è la migliore pratica comune di cui sono a conoscenza.
Ora considera un approccio diverso. Perderemo la proprietà monouso. Tuttavia, il vantaggio è che l'app non deve tenere traccia degli stati dei token.
Invece di generare un token casuale, useremo un HMAC come segue:
- token = HMAC_k (email, timestamp)
k è un segreto che l'app conosce sufficiente entropia. Il link di reset che viene inviato via email all'utente appare come segue:
Quando l'utente accede al collegamento, l'app lo verifica come segue:
- calcola HMAC in base ai parametri URL: token_calculated = HMAC_k (email, timestamp)
- controlla se il token fornito come parametro URL e la corrispondenza HMAC calcolata
- se sì, controlla se il token è ancora valido in base al timestamp
- se sì, consenti all'utente di accedere alla pagina resetPassword
A mio parere, la proprietà di non dover mantenere uno stato lato server è più preziosa della proprietà monouso. Ciò presuppone che una validità ragionevole e breve di token sia configurata sul lato server, ad esempio da 20 a 30 minuti.
Mi piacerebbe davvero sapere cosa pensano gli altri del secondo approccio. Soprattutto, se ci sono degli svantaggi che non avrei ancora notato.
[1] link
[2] link