Se hai solo bisogno di fornire l'autenticazione ma i dati trasmessi via cavo non sono sensibili, allora c'è un modo migliore senza il sovraccarico / la latenza di SSL.
Supponiamo di avere un'app client mobile; per prima cosa iscrivere o registrare l'utente fornendo la propria email (nome utente) e la password in un modulo Web separato (non facente parte dell'app o del servizio REST). Quindi, una volta completata la registrazione, si risponde con una chiave utente (può essere una chiave segreta condivisa memorizzata nell'account utente sul server (database) per la crittografia simmetrica o una chiave pubblica per la crittografia asimmetrica in cui la chiave privata corrispondente è memorizzata nell'account utente sul server (database). Tutto questo viene fatto utilizzando un modulo Web su SSL.
Ora, quando l'utente apre l'app client, è necessario chiedere loro le credenziali che verranno inviate con ogni richiesta al servizio RESTful. Devono fornire il loro nome, password e chiave di crittografia che hanno ricevuto in precedenza. Questo deve essere fatto solo una volta. L'app fornisce quindi un header http con ogni richiesta che assomiglia a questo:
AUTENTICAZIONE > username: timestamp: crittografato {password: timestamp} / AUTHENTICATE >
Si noti che sia la password che il timestamp all'interno di {} vengono crittografati utilizzando la chiave dell'utente. Il timestamp viene aggiornato con ogni singola richiesta.
Implementa un filtro di autenticazione sul server che effettua le seguenti operazioni:
Prima controlla il timestamp e se scaduto (diciamo più vecchio di 1 secondo) invia un codice di risposta HTTP NON AUTORIZZATO. Se il timestamp è valido, cerca il nome utente nel tuo database degli account utente. Se non trovato, invia una risposta HTTP NON AUTORIZZATA. Se viene trovato il nome utente, recuperare la chiave di crittografia memorizzata per quell'utente (ricordare che questa può essere una chiave segreta condivisa o la chiave privata per la chiave pubblica dell'utente). Decifrare la {password: timestamp} crittografata. La password rifiutata deve corrispondere alla password dell'utente memorizzata nel database (la password stessa potrebbe anche essere inclusa nel database utilizzando un'altra chiave per maggiore sicurezza) e la data / ora decrittografata deve corrispondere anche al timestamp non crittografato inviato nell'intestazione AUTHENTICATE sopra. In caso contrario, inviare un codice di risposta HTTP NON AUTORIZZATO. In caso di esito positivo la richiesta è stata autenticata senza l'uso di cookie / sessioni.
Puoi anche memorizzare nella cache i dettagli dell'utente per evitare di eseguire una ricerca nel database ad ogni richiesta.
Ora, se qualcuno sta indagando e intercetta la richiesta, non sarà in grado di riutilizzarla per ottenere l'accesso perché la data / ora non sarà valida o, se aggiornerà la data / ora non crittografata per essere valida, non corrisponderà alla crittografia timestamp (dopo che il filtro di autenticazione lo ha decrittografato).
Un altro vantaggio di questo approccio rispetto all'utilizzo di una singola chiave dell'app è che ora hai il controllo completo su chi può accedere al tuo servizio inserendo una data di scadenza sull'account utente nel database (implementando in modo efficace un servizio basato su abbonamento). Questo è ottimo perché all'inizio potresti voler ottenere il maggior numero possibile di utenti con un abbonamento di prova (gratuito per esempio 1 anno) e poi bloccare l'accesso a quell'utente se non hanno pagato per estendere la data di scadenza dell'account:)