use*_*113 11 python http http-headers python-requests authorization-header
我正在尝试使用 Python requests 库发出 API POST 请求。我正在传递一个Authorization标头,但是当我尝试调试时,我可以看到标头正在被删除。我不知道是怎么回事。
这是我的代码:
access_token = get_access_token()
bearer_token = base64.b64encode(bytes("'Bearer {}'".format(access_token)), 'utf-8')
headers = {'Content-Type': 'application/json', 'Authorization': bearer_token}
data = '{"FirstName" : "Jane", "LastName" : "Smith"}'
response = requests.post('https://myserver.com/endpoint', headers=headers, data=data)
Run Code Online (Sandbox Code Playgroud)
正如您在上面看到的,我Authorization在请求参数中手动设置了标头,但它缺少实际请求的标头:
{'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'python-requests/2.4.3 CPython/2.7.9 Linux/4.1.19-v7+'}。
另外一条信息是,如果我将 POST 请求更改为 GET 请求,则Authorization标头会正常通过!
为什么这个库会丢弃 POST 请求的标头,我该如何让它工作?
使用请求库的 v2.4.3 和 Python 2.7.9
kma*_*ork 18
TLDR
您请求的 url 将 POST 请求重定向到不同的主机,因此请求库会删除Authoriztion标头,以免泄露您的凭据。要解决这个问题,您可以覆盖请求Session类中的负责方法。
细节
在请求 2.4.3 中,reqeuests删除Authorization标头的唯一地方是当请求被重定向到不同的主机时。这是相关代码:
Run Code Online (Sandbox Code Playgroud)if 'Authorization' in headers: # If we get redirected to a new host, we should strip out any # authentication headers. original_parsed = urlparse(response.request.url) redirect_parsed = urlparse(url) if (original_parsed.hostname != redirect_parsed.hostname): del headers['Authorization']
在较新版本的 中requests,Authorization标头将在其他情况下被删除(例如,如果重定向是从安全协议到非安全协议)。
因此,在您的情况下可能发生的情况是您的 POST 请求被重定向到不同的主机。您可以使用请求库为重定向主机提供身份验证的唯一方法是通过.netrc文件。遗憾的是,这只允许您使用 HTTP 基本身份验证,这对您没有多大帮助。在这种情况下,最好的解决方案可能是子类化requests.Session并覆盖此行为,如下所示:
from requests import Session
class NoRebuildAuthSession(Session):
def rebuild_auth(self, prepared_request, response):
"""
No code here means requests will always preserve the Authorization
header when redirected.
Be careful not to leak your credentials to untrusted hosts!
"""
session = NoRebuildAuthSession()
response = session.post('https://myserver.com/endpoint', headers=headers, data=data)
Run Code Online (Sandbox Code Playgroud)
编辑
我已经向 github 上的请求库打开了一个拉取请求,以在发生这种情况时添加警告。它一直在等待第二次批准合并(已经三个月了)。