파이썬 요청 : 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 요청에 대한 헤더를 삭제하는 이유는 무엇이며 어떻게 작동합니까?

lib 및 Python 2.7.9 요청의 v2.4.3 사용

답변:


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 Basic Auth 만 사용할 수 있으므로 크게 도움이되지 않습니다. 이 경우 가장 좋은 해결책은 다음 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__.
Monica Monica 복원

질문에 설명 된 동작은 변경되지 않습니다. 리디렉션에서 인증을 다시 작성할 때 요청은 auth 인수를 사용하지 않습니다.
kmaork
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.