嗯,我猜你的问题是身份验证。您没有展示在Python中是如何做到这一点的,但是我想这是有原因的,因为您在拥有body(json.dumps调用)之前就计算了body_md5_str和{}),所以它一定有问题。您是否确保您的代码生成与JS和PHP代码相同的值?在
就个人而言,我将实现一个身份验证类,它将在请求触发之前添加必要的头。有关详细信息,请参阅requests documentation on custom auth,如果我的详细信息是正确的,下面是我的(未测试)尝试:import requests
import hashlib
import hmac
import base64
from wsgiref.handlers import format_date_time
import datetime
from time import mktime
CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
class OnlinePBXAuth(requests.auth.AuthBase):
def __init__(self, key_id, secret):
self.key_id = key_id
self.secret = secret
def __call__(self, r):
content_type = r.headers.get("Content-Type", CONTENT_TYPE_FORM_URLENCODED)
body = r.body or ""
body_md5 = hashlib.md5(body).hexdigest()
date = format_date_time(mktime(datetime.datetime.now().timetuple()))
date = r.headers.get("Date", date)
r.headers["Date"] = date
r.headers["X-PBX-Date"] = date
sign = "\n".join([r.method, body_md5, content_type, date, r.url, ""])
signature = base64.b64encode(hmac.new(self.secret, sign, hashlib.sha1).hexdigest())
r.headers["Content-MD5"] = body_md5
r.headers["X-PBX-Authentication"] = "{0}:{1}".format(self.key_id, signature)
return r
不是最漂亮的代码,但我想这应该能解决问题。在
然后,像这样使用它:
^{pr2}$
或者像这样:session = requests.Session(auth=OnlinePBXAuth(KEY_ID, KEY_SECRET))
...
r1 = session.post(url, data)
...
r2 = session.post(another_url, another_data)
我不确定它是否能处理空体请求(像大多数GETs一样)和多部分分块体(因此,请自行计算或尽量避免这些),但我认为对于application/x-www-form-urlencoded和application/json编码的数据应该没问题。在