Python żąda biblioteki, jak przekazać nagłówek Authorization z pojedynczym tokenem

98

Mam identyfikator URI żądania i token. Jeśli używam:

curl -s "<MY_URI>" -H "Authorization: TOK:<MY_TOKEN>"

itd., otrzymuję 200 i wyświetlam odpowiednie dane JSON. Tak więc zainstalowałem żądania i kiedy próbuję uzyskać dostęp do tego zasobu, otrzymuję kod 403 prawdopodobnie dlatego, że nie znam prawidłowej składni do przekazania tego tokenu. Czy ktoś może mi pomóc to rozgryźć? Oto co mam:

import sys,socket
import requests

r = requests.get('<MY_URI>','<MY_TOKEN>')
r. status_code

Już próbowałem:

r = requests.get('<MY_URI>',auth=('<MY_TOKEN>'))
r = requests.get('<MY_URI>',auth=('TOK','<MY_TOKEN>'))
r = requests.get('<MY_URI>',headers=('Authorization: TOK:<MY_TOKEN>'))

Ale żadna z tych rzeczy nie działa.


źródło

Odpowiedzi:

113

W Pythonie:

('<MY_TOKEN>')

jest równa

'<MY_TOKEN>'

I prośby interpretują

('TOK', '<MY_TOKEN>')

Jeśli chcesz, aby żądania korzystały z uwierzytelniania podstawowego i utworzyły nagłówek autoryzacji w następujący sposób:

'VE9LOjxNWV9UT0tFTj4K'

Który jest reprezentacją base64 'TOK:<MY_TOKEN>'

Aby przekazać swój własny nagłówek, przekazujesz w słowniku taki jak ten:

r = requests.get('<MY_URI>', headers={'Authorization': 'TOK:<MY_TOKEN>'})
Ian Stapleton Cordasco
źródło
Traceback (ostatnie połączenie): plik „<stdin>”, wiersz 1, w <module> File ”/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ”, wiersz 55, w żądaniu zwrotu get ('get', url, ** kwargs) File" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", wiersz 44, w żądaniu zwraca session.request (metoda = metoda, url = url, ** kwargs) Plik" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages /requests/sessions.py ", wiersz 323, w żądaniu prep = self.prepare_request (req)
@rebHelium można GIST , że? To nie jest cały ślad stosu i nic nie wskazuje na to, co faktycznie próbowałeś.
Ian Stapleton Cordasco,
Przepraszamy, przepełnienie stosu nie pozwoliło mi opublikować całego wyniku. Zrobiłem dokładnie tak, jak zasugerowałeś: r = requests.get ('cokolwiek mam url', headers = {'Authorization': 'TOK: jaki token mam'})
Nie ma potrzeby przepraszać. Zadziałało? Przyjąłeś moją odpowiedź, ale wydaje się, że spowodowała to dla ciebie wyjątek. Jeśli utworzysz streszczenie , mogę Ci pomóc z większą łatwością niż rozmowa tutaj.
Ian Stapleton Cordasco
Sigma, właściwie przegapiłem jeden mały szczegół w twoim kodzie, który spowodował błąd. Rzeczywisty kod jest poufny, więc nie mogę streścić. Ale opublikuję dodatkowe pytania, ponieważ chcę poprawić swoje umiejętności w Pythonie, jeśli chcesz spojrzeć. Są to bardzo proste pytania, które na pewno znasz.
38

Szukałem czegoś podobnego i trafiłem na to . Wygląda na to, że w pierwszej wspomnianej opcji

r = requests.get('<MY_URI>', auth=('<MY_TOKEN>'))

„auth” przyjmuje dwa parametry: nazwę użytkownika i hasło, więc właściwa instrukcja powinna być

r=requests.get('<MY_URI>', auth=('<YOUR_USERNAME>', '<YOUR_PASSWORD>'))

W moim przypadku nie było hasła, więc zostawiłem drugi parametr w polu auth pusty, jak pokazano poniżej:

r=requests.get('<MY_URI', auth=('MY_USERNAME', ''))

Mam nadzieję, że to komuś pomoże :)

BajajG
źródło
3
jeśli spróbujesz r = requests.get('<MY_URI>',auth=('<MY_TOKEN>')), otrzymasz TypeError: 'str' object is not callable. to mnie
zaskoczyło,
Twój anserd pomógł mi, ale dopiero po przeczytaniu podanego przez Ciebie linku, z którego przyszedłeś. Praca z importem HTTPBasicAuth z request.auth sprawia, że ​​jest to bardzo proste!
Wallem89
27

To zadziałało dla mnie:

access_token = #yourAccessTokenHere#

result = requests.post(url,
      headers={'Content-Type':'application/json',
               'Authorization': 'Bearer {}'.format(access_token)})
Edgar N
źródło
16

Możesz także ustawić nagłówki dla całej sesji:

TOKEN = 'abcd0123'
HEADERS = {'Authorization': 'token {}'.format(TOKEN)}

with requests.Session() as s:

    s.headers.update(HEADERS)
    resp = s.get('http://example.com/')
Anton Tarasenko
źródło
4

Żądania natywnie obsługują podstawowe uwierzytelnianie tylko z parametrami przepustki użytkownika, a nie z tokenami.

Jeśli chcesz, możesz dodać następującą klasę, aby żądania obsługiwały uwierzytelnianie podstawowe oparte na tokenach:

import requests
from base64 import b64encode

class BasicAuthToken(requests.auth.AuthBase):
    def __init__(self, token):
        self.token = token
    def __call__(self, r):
        authstr = 'Basic ' + b64encode(('token:' + self.token).encode('utf-8')).decode('utf-8')
        r.headers['Authorization'] = authstr
        return r

Następnie, aby go użyć, uruchom następujące żądanie:

r = requests.get(url, auth=BasicAuthToken(api_token))

Alternatywą byłoby sformułowanie zamiast tego niestandardowego nagłówka, tak jak sugerowali inni użytkownicy tutaj.

Amit Blum
źródło
4

założyłem tutaj, jest ze mną ok dla linkedin: https://auth0.com/docs/flows/guides/auth-code/call-api-auth-code, więc mój kod z loginem linkedin tutaj:

ref = 'https://api.linkedin.com/v2/me'
headers = {"content-type": "application/json; charset=UTF-8",'Authorization':'Bearer {}'.format(access_token)}
Linkedin_user_info = requests.get(ref1, headers=headers).json()
Tri Tran
źródło
2

Możesz spróbować czegoś takiego

r = requests.get(ENDPOINT, params=params, headers={'Authorization': 'Basic %s' %  API_KEY})
swatisinghi
źródło
2

To zadziałało dla mnie:

r = requests.get('http://127.0.0.1:8000/api/ray/musics/', headers={'Authorization': 'Token 22ec0cc4207ebead1f51dea06ff149342082b190'})

Mój kod używa tokena wygenerowanego przez użytkownika.

Reymond Joseph
źródło