Библиотека запросов Python, как передать заголовок авторизации с помощью одного токена

95

У меня есть URI запроса и токен. Если я использую:

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

и т.д., я получаю 200 и просматриваю соответствующие данные JSON. Итак, я установил запросы, и когда я пытаюсь получить доступ к этому ресурсу, я получаю 403, вероятно, потому, что я не знаю правильный синтаксис для передачи этого токена. Может ли кто-нибудь помочь мне разобраться? Вот что у меня есть:

import sys,socket
import requests

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

Я уже пробовал:

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

Но ничего из этого не работает.


источник

Ответы:

112

В питоне:

('<MY_TOKEN>')

эквивалентно

'<MY_TOKEN>'

И запросы интерпретирует

('TOK', '<MY_TOKEN>')

Поскольку вы хотите, чтобы запросы использовали базовую аутентификацию и создавали заголовок авторизации следующим образом:

'VE9LOjxNWV9UT0tFTj4K'

Какое представление base64 'TOK:<MY_TOKEN>'

Чтобы передать свой собственный заголовок, вы передаете словарь следующим образом:

r = requests.get('<MY_URI>', headers={'Authorization': 'TOK:<MY_TOKEN>'})
Ян Стэплтон Кордаско
источник
Traceback (последний вызов последним): файл «<stdin>», строка 1, в <module> File «/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api. .py ", строка 55, в файле запроса на возврат ('get', url, ** kwargs)" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", строка 44, в запросе return session.request (method = method, url = url, ** kwargs) File" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages /requests/sessions.py ", строка 323, в запросе prepare = self.prepare_request (req)
@rebHelium вы можете GIST , что? Это не вся трассировка стека, и нет никаких указаний на то, что вы на самом деле пробовали.
Ян Стэплтон Кордаско
Извините, переполнение стека не позволило мне опубликовать весь вывод. Я сделал именно то, что вы предложили: r = requests.get ('любой URL-адрес, который у меня есть', headers = {'Авторизация': 'TOK: любой токен, который у меня есть'})
Не нужно извиняться. Это сработало? Вы приняли мой ответ, но, похоже, он вызвал для вас исключение. Если вы создадите суть, я могу помочь вам с большей легкостью, чем разговор здесь.
Ян Стэплтон Кордаско
Сигма, я на самом деле пропустил одну маленькую деталь в вашем коде, которая вызвала ошибку. Фактический код является конфиденциальным, поэтому я не могу сказать. Но я опубликую дополнительные вопросы, так как хочу улучшить свои навыки Python, если хотите. Это очень простые вопросы, я уверен, что вы их знаете.
37

Искал нечто подобное и наткнулся на это . Похоже, что в первом упомянутом вами варианте

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

"auth" принимает два параметра: имя пользователя и пароль, поэтому фактическая инструкция должна быть

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

В моем случае пароля не было, поэтому я оставил второй параметр в поле auth пустым, как показано ниже:

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

Надеюсь, это кому-то поможет :)

BajajG
источник
3
если попробуешь r = requests.get('<MY_URI>',auth=('<MY_TOKEN>')), получишь TypeError: 'str' object is not callable. это озадачило меня на некоторое время, пока я не наткнулся на это: /
aydow
Ваш ансерд помог мне, но только после прочтения предоставленной вами ссылки, по которой вы пришли. Работать с импортом HTTPBasicAuth из requests.auth очень просто!
Wallem89
26

Это сработало для меня:

access_token = #yourAccessTokenHere#

result = requests.post(url,
      headers={'Content-Type':'application/json',
               'Authorization': 'Bearer {}'.format(access_token)})
Эдгар Н
источник
16

Вы также можете установить заголовки для всего сеанса:

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

with requests.Session() as s:

    s.headers.update(HEADERS)
    resp = s.get('http://example.com/')
Антон Тарасенко
источник
4

Запросы изначально поддерживают базовую аутентификацию только с параметрами передачи пользователя, а не с токенами.

При желании вы можете добавить следующий класс, чтобы запросы поддерживали базовую аутентификацию на основе токенов:

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

Затем, чтобы использовать его, выполните следующий запрос:

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

Альтернативой может быть формулировка собственного заголовка, как было предложено здесь другими пользователями.

Амит Блюм
источник
3

Я основал здесь, со мной все в порядке для linkedin: https://auth0.com/docs/flows/guides/auth-code/call-api-auth-code, поэтому мой код с входом в linkedin здесь:

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()
Три Тран
источник
2

Вы можете попробовать что-то вроде этого

r = requests.get(ENDPOINT, params=params, headers={'Authorization': 'Basic %s' %  API_KEY})
Swatisinghi
источник
0

Это сработало для меня:

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

В моем коде используется токен, созданный пользователем.

Реймонд Джозеф
источник