我希望在 Django 之上实现一个公共(编辑:更确切地说,一个公开的经过身份验证的 api)API,而Django Rest Framework似乎是一个流行的选择。我习惯使用的 API 通常要求请求包含 API 密钥、随机数和 HMAC。
查看身份验证页面,我发现最接近内置 API 密钥的是JSON web token authentication。
我想设计一个可以防止窃听和重放攻击的 API。如果我要手动实现这一点,我的直觉是为用户生成 API 密钥和秘密对,并让他们签署这样的请求:
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)
然后我会在服务器端验证:
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")
我想知道
- 我可以通过 Django Rest Framework 执行此操作吗?如果没有,是否有 Django 包可以执行此操作?(如果这不可能,是否有没有实施的原因?)
- 考虑到我的目标,这是一个安全的身份验证方案吗(只有拥有令牌的人才能生成有效请求,没有重播等)?
- 有没有更好、更惯用的方法?
- 是否甚至有必要寻求第三方库,或者边缘案例是否足够有限,以至于家庭酿造的解决方案——伴随着单元测试——就足够了?