पायथन अनुरोध: प्राधिकरण अनुरोध छोड़ने वाले POST अनुरोध


9

मैं पायथन अनुरोध लाइब्रेरी का उपयोग करके एक एपीआई पोस्ट अनुरोध बनाने की कोशिश कर रहा हूं। मैं एक 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+'}:।

जानकारी का एक अतिरिक्त टुकड़ा यह है कि अगर मैं पोस्ट अनुरोध को जीईटी अनुरोध में बदलता हूं, तो Authorizationहेडर सामान्य रूप से गुजरता है!

यह लाइब्रेरी POST अनुरोधों के लिए शीर्ष लेख क्यों छोड़ रही है और मुझे यह कैसे काम करना है?

अनुरोधों के v2.4.3 का उपयोग करना आवश्यक है और अजगर 2.7.9

जवाबों:


10

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

के नए संस्करणों में requests, Authorizationहेडर को अतिरिक्त मामलों में छोड़ दिया जाएगा (उदाहरण के लिए यदि रीडायरेक्ट सुरक्षित से गैर-सुरक्षित प्रोटोकॉल में है)।

तो शायद आपके मामले में क्या होता है, यह कि आपके पोस्ट अनुरोध एक अलग होस्ट पर पुनर्निर्देशित हो जाते हैं। जिस तरह से आप अनुरोध लायब्रेरी का उपयोग करके पुनर्निर्देशित होस्ट के लिए प्रमाणीकरण प्रदान कर सकते हैं, वह एक .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केवल सर्वर द्वारा अनुरोध किए गए पुनर्निर्देशन का पालन करने से अनुरोधों को रोक देगा। यह अनुरोध को पूरा करने में मदद नहीं करेगा, यह इसे बीच में ही रोक देगा।
कर्मांक

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__
मोनिका

यह प्रश्न में वर्णित व्यवहार को नहीं बदलेगा। जब रीडायरेक्ट पर पुनरीक्षण को फिर से बनाया जाता है, तो अनुरोध दलील का उपयोग नहीं करते हैं।
कर्मांक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.