Python请求:POST请求删除了Authorization标头 [英] Python requests: POST request dropping Authorization header

查看:670
本文介绍了Python请求:POST请求删除了Authorization标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python请求库发出API POST请求.我正在通过Authorization标头,但是当我尝试调试时,可以看到标头被删除了.我不知道发生了什么事.

I'm trying to make an API POST request using the Python requests library. I am passing through an Authorization header but when I try debugging, I can see that the header is being dropped. I have no idea what's going on.

这是我的代码:

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)

如上所述,我在请求参数中手动设置了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+'}.

As you can see above, I manually set the Authorization header in the request arguments, but it is missing the actual request's headers: {'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标头会正常通过!

An additional piece of information is that if I change the POST request to a GET request, the Authorization header passes through normally!

为什么该库会丢弃POST请求的标头,如何使它正常工作?

Why would this library be dropping the header for POST requests and how do I get this to work?

使用v2.4.3的请求lib和Python 2.7.9

Using v2.4.3 of the requests lib and Python 2.7.9

推荐答案

TLDR

您请求的URL将POST请求重定向到其他主机,因此,请求库会丢弃Authoriztion标头,以免泄漏凭据.要解决此问题,您可以覆盖请求的Session类中的负责方法.

The url you are requesting redirects POST requests to a different host, so the requests library drops the Authoriztion header in fear of leaking your credentials. To fix that you can override the responsible method in requests' Session class.

详细信息

在请求2.4.3中,reqeuests删除Authorization标头的唯一位置是将请求重定向到其他主机时. 这是相关代码:

In requests 2.4.3, the only place where reqeuests removes the Authorization header is when a request is redirected to a different host. This is the relevant code:

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标头.

In newer versions of requests, the Authorization header will be dropped in additional cases (for example if the redirect is from a secure to a non-secure protocol).

因此,在您的情况下可能会发生的情况是,您的POST请求被重定向到其他主机.使用请求库为重定向主机提供身份验证的唯一方法是通过.netrc文件.可悲的是,这仅允许您使用HTTP Basic Auth,这对您没有太大帮助.在这种情况下,最好的解决方案可能是requests.Session的子类并覆盖此行为,如下所示:

So what probably happens in your case, is that your POST requests get redirected to a different host. The only way you can provide authentication for a redirected host using the requests library, is through a .netrc file. Sadly that will only allow you to use HTTP Basic Auth, which doesn't help you much. In that case, the best solution is probably to subclass requests.Session and override this behavior, like so:

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)

修改

我在github上的请求库中打开了 pull-request 发生这种情况时发出警告.它一直在等待第二次批准合并(已经三个月了).

I have opened a pull-request to the requests library on github to add a warning when this happens. It has been waiting for a second approval to be merged (three months already).

这篇关于Python请求:POST请求删除了Authorization标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆