使用自定义认证修改请求参数
我刚把我的请求库升级到了2.3.0(之前是0.14.0),结果我的自定义认证功能不再正常工作了。问题在于,我们的自定义认证会在请求中添加一个API密钥和一个时间戳,这样我们所有的辅助方法就不用每次都加这些东西。
class APIAuth(requests.auth.AuthBase):
def __call__(self, request):
api_secret = settings.API_SHARED_SECRET
api_key = settings.API_KEY
request.params.update(dict(
api_key=api_key,
timestamp=int(time.time()*1000)))
signature = base64.b64encode(hmac.new(
api_secret,
msg=unquote(request.full_url),
digestmod=hashlib.sha256
).digest()).decode()
request.headers['Authorization'] = "signature {0}".format(signature)
return request
出现的错误是:
AttributeError: 'PreparedRequest' object has no attribute 'params'
准备好的请求不允许修改参数字典,可能是因为它已经构建完成了。有没有简单的方法可以从我们的自定义认证中更新参数字典,同时保留现有的参数不变?还是说我必须忍痛割爱,每个请求方法都得手动加这两个参数?
1 个回答
7
没错,现在传入的是一个 PreparedRequest
,而且URL的查询字符串已经根据参数设置好了。
不过,PreparedRequest.prepare_url()
方法可以让你 更新 URL,添加更多的参数:
class APIAuth(requests.auth.AuthBase):
def __call__(self, request):
api_secret = settings.API_SHARED_SECRET
api_key = settings.API_KEY
request.prepare_url(request.url, dict(
api_key=api_key,
timestamp=int(time.time()*1000)))
signature = base64.b64encode(hmac.new(
api_secret,
msg=unquote(request.full_url),
digestmod=hashlib.sha256
).digest()).decode()
request.headers['Authorization'] = "signature {0}".format(signature)
return request
示例:
>>> import requests
>>> prepared = requests.Request(url='http://httpbin.org/get').prepare()
>>> prepared.url
'http://httpbin.org/get'
>>> prepared.prepare_url(prepared.url, {'foo': 'bar', 'spam': 42})
>>> prepared.url
'http://httpbin.org/get?foo=bar&spam=42'
>>> prepared.prepare_url(prepared.url, {'monty': 'python'})
>>> prepared.url
'http://httpbin.org/get?foo=bar&spam=42&monty=python'
通过传入 prepared.url
,URL会被更新,添加额外的参数。新的参数总是 附加 的;如果新参数和已经添加的参数名字相同,旧的参数不会被删除。