Sto cercando di implementare un'API pubblica (modifica: piuttosto, un'autentica API esposta a Internet) su Django e Django Rest Framework sembra essere una scelta popolare. Le API con le quali sono abituato a lavorare solitamente richiedono che le richieste contengano una chiave API, un nonce e quindi un HMAC.
Guardando la pagina di autenticazione, vedo che la cosa più vicina a una chiave API incorporata è autenticazione token web JSON .
Mi piacerebbe progettare un'API sicura contro gli attacchi di intercettazione e riproduzione. Se dovessi implementarlo a mano, il mio istinto sarebbe quello di generare API key & coppie segrete per gli utenti e farle firmare richieste come queste:
import hmac, hashlib, time
API_KEY, API_SECRET = # loaded from environment
BASE_URL = "https://myservice/api/v1/"
def signed_request(method, endpoint, body=None):
nonce = str(int(round(time.time() * 1000)))
to_sign = nonce + method + endpoint + (body or '')
sig = hmac.new(API_SECRET, to_sign, hashlib.sha256).hexdigest()
headers = {
'key' : API_KEY,
'signature' : sig,
'nonce' : nonce
}
# Actually make the request
do_the_request(method, BASE_URL + endpoint, body, headers)
Vorrei quindi verificare sul lato server che:
def verify_request(method, endpoint, body, headers):
secret = get_secret_from_database(api_key=headers['key'])
verify = headers['nonce'] + method + endpoint + body
valid_sig = hmac.new(secret, verify, hashlib.sha256).hexdigest() == headers['sig']
valid_nonce = int(headers['nonce']) > get_last_nonce_from_database(api_key=headers['key'])
if valid_sig and valid_nonce:
# Valid message
else:
raise Exception("Bad signature")
Mi piacerebbe sapere
- Posso farlo tramite il Django Rest Framework e, se no, c'è un pacchetto per Django che lo fa? (Se questo non è possibile, c'è un motivo per cui non è implementato?)
- Si tratta di uno schema di autenticazione sicuro in base ai miei obiettivi (solo la persona in possesso del token può generare richieste valide, senza replay, ecc.)?
- C'è un approccio migliore, più idiomatico?
- È anche necessario cercare una libreria di terze parti, o i casi limite sono abbastanza limitati che una soluzione prodotta in casa - accompagnata da test unitari - è sufficiente?