Autenticazione
L'autenticazione sarà basata sulla firma. La firma verrà generata utilizzando:
HMAC_SHA256(SHA1(secret_key) + '#' + request_data + '#' + utc_timestamp)
Anche utc_timestamp
verrà incluso nell'intestazione X-Timestamp
o nell'URL utilizzando il parametro _timestamp
. Il request_data
conterrà tutti i parametri (URL e POST) e le intestazioni relative alle API. Tutti questi dati saranno in minuscolo, ordinati e uniti usando =
e &
.
Generalmente, l'API REST supporterà tre schemi di autenticazione:
-
Chiavi API basate: la firma includerà la chiave segreta speciale associata alla particolare chiave API. Utilizzerà l'intestazione
X-API-Key
o il parametro_api_key
URL e l'intestazioneX-API-Signature
o il parametro_signature
URL. -
Credenziali utente in base: la firma utilizzerà la password come chiave segreta. Utilizzerà l'intestazione
X-API-Signature
o il parametro_signature
URL e il parametrostaff_name
URL. -
Sessione in base: la firma utilizzerà la password dell'utente o un codice appositamente creato (ulteriori dettagli di seguito) ... utilizzerà l'intestazione
X-Session-Signature
oppure il parametro_session_signature
URL e l'intestazioneX-Session-ID
o il parametro_session_id
URL.
Tieni presente che la specifica consente di utilizzare Credenziali utente e Sessione contemporaneamente (ovvero, le intestazioni e i parametri non sono in conflitto).
Sessione
Disclaimer: Sì, lo so - le sessioni non sono RESTful, poiché sono stateful ... Tuttavia, il nostro prodotto richiede sessioni per alcune funzionalità e, per ragioni di semplicità, vogliamo mantenere una API / protocollo - quindi non sto cercando di entrare in un dibattito RESTful. Preferisco pensare che una sessione sia solo una risorsa, che devi mantenere mentre lavori con l'API.
La sessione sarà solo una risorsa: /api/v1/session
.
Quindi, la procedura standard:
-
Per creare una sessione un'applicazione client dovrà inviare una richiesta POST utilizzando l'autenticazione credenziali dello staff , che è stata descritta sopra:
POST /api/v1/session&staff_name=s-andy
. -
Il server risponderà con
201 Created
e invierà l'ID di sessione nel corpo della risposta. -
Successivamente l'applicazione client utilizzerà questo ID di sessione e la password dello staff per accedere all'API.
Dopo aver ottenuto una richiesta con un particolare ID di sessione, il server aggiornerà l'ultima volta in cui è avvenuta l'accesso alla risorsa di sessione appropriata.
Ma i nostri utenti avranno anche un'opzione per usare l'autenticazione a due fattori. Nell'interfaccia utente dopo aver effettuato l'accesso a tali utenti verrà richiesto di inserire il codice di verifica , che arriverà ai propri dispositivi mobili. Quando ho progettato l'autenticazione ho pensato che sarebbe stato fantastico avere un "segreto" speciale invece della password dell'utente per la sessione. Poi mi sono reso conto: perché non utilizzare questo codice di verifica ?
Quindi il flusso per l'autenticazione a due fattori sarà:
-
Un'applicazione client invia una richiesta POST utilizzando le credenziali dello staff .
-
Il server avvia il codice di verifica generazione e consegna e restituisce
202 Accepted
con l'id di sessione, ma la sessione non è ancora stata verificata. -
Entro 30 secondi l'applicazione client invia qualsiasi richiesta utilizzando l'id di sessione nell'intestazione
X-Session-ID
o nel parametro_session_id
URL e il codice di verifica come segreto per generare la firma. -
Avendo ottenuto tale richiesta il server aggiorna la sessione facendola verificare e salva il codice di verifica (alias password unica) come chiave segreta per questa sessione.
-
Successivamente l'applicazione client utilizzerà l' id di sessione e il codice di verifica (come chiave segreta) per accedere all'API.
-
Quando la sessione scade e, pertanto, viene eliminata o quando l'utente elimina la sessione (cioè esegue la disconnessione), l'ID della sessione e la "password unica" diventano inutilizzabili.
Volevo utilizzare questa comunità di esperti come cassa di risonanza per questa idea di autenticazione a due fattori; riesci a vedere le insidie che non posso?