Sto costruendo un'applicazione web in cui il front-end è un'app a pagina singola e il back-end lo serve tramite un'API RESTful. Voglio assicurarmi di implementare l'autenticazione utente con le migliori pratiche di sicurezza.
Sto pianificando un sistema che eseguirà i seguenti passaggi per garantire la sicurezza dell'autenticazione:
Registrazione (o modifica della password):
- L'utente invia nome utente e password al server in testo in chiaro tramite HTTPS
- Unico salt viene generato con la funzione
urandom
di Python (32 caratteri) - Salt anteposto alla password
- Salt + password viene sottoposta a hash con
bcrypt
- Salt e hash memorizzati nella tabella del database (database SQL, più lento del valore-chiave ma non sono troppo preoccupato per la superspeed per l'accesso)
- ID sessione casuale generato con
urandom
(32 caratteri) - ID sessione memorizzato nel valore-chiave db (Chiave Redis: ID sessione, valore: id utente) e inviato al client insieme all'oggetto utente (ovviamente senza sale e hash)
Accesso:
- Al momento del login, l'utente invia nome utente e password al server in testo in chiaro tramite HTTPS
- Il server recupera il sale e l'hash dalla voce degli utenti in SQL db
- Salt anteposto alla password e passa attraverso
bcrypt
- Se entrambi gli hash corrispondono, l'ID di sessione viene generato con
urandom
e inserito nel valore-chiave db - ID sessione inviato al client con oggetto utente
Qualsiasi altra richiesta al server:
- Richiesta e dati inviati tramite HTTPS inclusi ID utente e ID sessione
- Valore chiave db cercato con ID utente, se gli ID sessione corrispondono, restituiscono i dati richiesti insieme all'oggetto utente
- Se non corrisponde, restituisci l'errore 401
Gestione sessione:
- Permetti più di una sessione per lo stesso utente
- Imposta la scadenza della sessione a 24 ore, quando si accede, torna a 24 ore
- Permetti la sessione persistente che scade tra 1 mese, quando si accede anche al tempo di scadenza completo
- Al logout, rimuovi la sessione da Redis
Sarà un sistema sicuro, scalabile e veloce (quando necessario)? Se no, dove sono i difetti di sicurezza? Cosa potrei fare per migliorare questo processo? È vulnerabile agli attacchi CSRF? Migliora la sicurezza per aggiungere l'indirizzo IP del client e USER_AGENT alla sessione o è eccessivo?