Pythonリクエスト:Authorizationヘッダーを削除するPOSTリクエスト


9

Pythonリクエストライブラリを使用して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)

上記のよう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を使用する

回答:


9

TLDR

リクエストしているURLはPOSTリクエストを別のホストにリダイレクトするため、リクエストライブラリはAuthoriztion認証情報の漏洩を恐れてヘッダーをドロップします。これを修正するには、リクエストのSessionクラスで責任のあるメソッドをオーバーライドできます。

細部

リクエスト2.4.3では、ヘッダーがreqeuests削除される唯一の場所Authorizationは、リクエストが別のホストにリダイレクトされるときです。これは関連するコードです

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

の新しいバージョンではrequestsAuthorization追加のケースでヘッダーがドロップされます(たとえば、リダイレクトがセキュアなプロトコルから非セキュアなプロトコルへの場合)。

したがって、あなたのケースでおそらく起こるのは、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)

1
ありがとう、これが問題でした!
user4184113

0

これはリクエストドキュメントが言うことです:

Authorization headers set with headers= will be overridden if credentials are specified in .netrc, which in turn will be overridden by the auth= parameter. Authorization headers will be removed if you get redirected off-host.

リクエストでリダイレクトされますか?

この場合は、ポストリクエストでこのオプションを使用してリダイレクトを無効にしてください。

allow_redirects=False


allow_redirects=Falseサーバーから要求されたリダイレクトに要求が従わないようにするだけです。これはリクエストの完了には役立ちませんが、途中で停止するだけです。
kmaork

0

私が目にする最初の(そしておそらく実際の)問題はbearer_token、トークンだけでなく認証タイプもエンコードしているため、作成方法です'Bearer'

私が理解したように、トークンをエンコードするだけで、空の認証タイプ+リクエストヘッダー内にエンコードされたトークンを提供する必要があります。

bearer_token = str(base64.b64encode(access_token.encode()), "utf8")
headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(bearer_token)}

それが(また)リダイレクトの問題である場合は、正しい場所を見つけてこのURLにリクエストを送信するPOSTか、サーバーがこれを受け入れている場合は、本文内にアクセストークンを送信することを検討してください。


0

ドキュメントから: Requests will attempt to get the authentication credentials for the URL’s hostname from the user’s netrc file. The netrc file overrides raw HTTP authentication headers set with headers=. If credentials for the hostname are found, the request is sent with HTTP Basic Auth.

リダイレクトされている場合は、 allow_redirects=false


-1

ヘッダーでカスタム認証を使用してみることができます。

カスタム認証クラスを定義します。

class MyAuth(requests.auth.AuthBase):
def __init__(self, bearer_token):
    self.username = None
    self.bearer_token = bearer_token

def __call__(self, r):
    r.headers['Authorization'] = self.bearer_token
    return r

次に、これを使用してリクエストを送信します。

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

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

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

これが機能する場合は、答えを受け入れてください。それでも問題が解決しない場合は、お知らせください。お役に立てれば。


から継承する必要はありませんrequests.auth.AuthBase。それのソースコードを見るとNotImplemented、オーバーライドを忘れた場合に発生するのはレイズだけであることがわかります__call__
モニカを復活

これは質問で説明されている動作を変更しません。リダイレクトで認証を再構築するとき、リクエストはauth引数を使用しません。
kmaork
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.