Estoy buscando implementar una API pública (edición: más bien, una API autenticada expuesta a Internet) sobre Django, y Django Rest Framework parece ser una opción popular. Las API con las que estoy acostumbrado a trabajar generalmente requieren que las solicitudes contengan una clave de API, un nonce y luego un HMAC.
Al mirar la página de autenticación, veo que lo más parecido a una clave API que está integrada es autenticación JSON web token .
Me gustaría diseñar una API que sea segura contra ataques de espionaje y repetición. Si tuviera que implementar esto a mano, mi instinto sería generar la clave de API & Parejas secretas para usuarios y hacer que firmen solicitudes como esta:
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)
Luego verificaría en el servidor que:
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")
Me gustaría saber
- ¿Puedo hacer esto a través de Django Rest Framework, y si no hay un paquete para Django que haga esto? (Si esto no es posible, ¿hay alguna razón para que no se implemente?)
- ¿Es este un esquema de autenticación seguro dados mis objetivos (solo la persona que posee el token puede generar solicitudes válidas, sin repeticiones, etc.)?
- ¿Existe un enfoque mejor, más idiomático?
- ¿Es incluso necesario buscar una biblioteca de terceros, o los casos límite son lo suficientemente limitados como para que una solución elaborada en casa, acompañada de pruebas de unidad, sea suficiente?