Python POST request dropping Authorization header

user4184113 :

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.

Here's my code:

def make_post_request():

    access_token = get_access_token()
    bearer_token = base64.b64encode(bytes("'Bearer {}'".format(access_token)), 'utf-8')
    print bearer_token

    headers = {'Content-Type': 'application/json', 'Authorization': bearer_token}

    data = '{"FirstName" : "Jane", "LastName" : "Smith"}'

    response = requests.post('https://myserver.com/endpoint', headers=headers, data=data)

    print response.request.headers

    print response.text

The result of print response.request.headers is: {'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+'}

and the request fails with an error message saying 'invalid session ID' - which isn't surprising given that the Authorization header isn't present in the request headers.

Something really confusing I noticed was that if I change the POST request to be a GET request, it passes the header through!

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

Using v2.4.3 of the requests lib and Python 2.7.9

kmaork :

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']

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).

What probably happens in your case, is that your post request gets redirected to a different host. If you want to preserve authentication, requests allows you to do that only using a netrc file. Sadly that will only allow you to use HTTP Basic Auth, which seems to not be your authentication method. 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 your authorization 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)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=19836&siteId=1