Python solicita a la biblioteca cómo pasar el encabezado de autorización con un solo token

95

Tengo un URI de solicitud y un token. Si uso:

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

etc., obtengo un 200 y veo los datos JSON correspondientes. Entonces, instalé solicitudes y cuando intento acceder a este recurso obtengo un 403 probablemente porque no conozco la sintaxis correcta para pasar ese token. ¿Alguien puede ayudarme a resolverlo? Esto es lo que tengo:

import sys,socket
import requests

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

Ya probé:

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

Pero ninguno de estos funciona.


fuente

Respuestas:

112

En Python:

('<MY_TOKEN>')

es equivalente a

'<MY_TOKEN>'

Y solicita interpreta

('TOK', '<MY_TOKEN>')

Como desea que las solicitudes utilicen la autenticación básica y creen un encabezado de autorización como este:

'VE9LOjxNWV9UT0tFTj4K'

¿Cuál es la representación base64 de 'TOK:<MY_TOKEN>'

Para pasar su propio encabezado, pasa en un diccionario como este:

r = requests.get('<MY_URI>', headers={'Authorization': 'TOK:<MY_TOKEN>'})
Ian Stapleton Cordasco
fuente
Traceback (última llamada más reciente): Archivo "<stdin>", línea 1, en <módulo> Archivo "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", línea 55, en get return request ('get', url, ** kwargs) Archivo" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", línea 44, en request return session.request (método = método, url = url, ** kwargs) Archivo" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages /requests/sessions.py ", línea 323, en request prep = self.prepare_request (req)
@rebHelium puede que GIST que? Ese no es el seguimiento completo de la pila y no hay ninguna indicación de lo que realmente intentó.
Ian Stapleton Cordasco
Lo siento, Stack Overflow no me permitió publicar toda la salida. Hice exactamente lo que sugirió: r = request.get ('cualquier URL que tenga', headers = {'Authorization': 'TOK: cualquier token que tenga'})
No necesitas disculparte. ¿Funcionó? Aceptaste mi respuesta, pero parece que te ha hecho una excepción. Si crea una esencia , puedo ayudarlo con mayor facilidad que teniendo una conversación aquí.
Ian Stapleton Cordasco
Sigma, de hecho me perdí un pequeño detalle en su código que causó el error. El código real es confidencial, por lo que no puedo entenderlo. Pero publicaré preguntas adicionales ya que quiero mejorar mis habilidades en Python, si quieres mirar. Son preguntas muy simples que estoy seguro de que sabrá.
37

Estaba buscando algo similar y encontré esto . Parece que en la primera opción que mencionaste

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

"auth" toma dos parámetros: nombre de usuario y contraseña, por lo que la declaración real debe ser

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

En mi caso, no había contraseña, así que dejé vacío el segundo parámetro en el campo de autenticación como se muestra a continuación:

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

Espero que esto ayude a alguien :)

BajajG
fuente
3
si lo intentas r = requests.get('<MY_URI>',auth=('<MY_TOKEN>')), obtendrás TypeError: 'str' object is not callable. Eso me dejó perplejo por un tiempo hasta que me encontré con esto: /
aydow
Tu respuesta me ayudó, pero solo después de leer el enlace que proporcionaste. ¡Trabajar con la importación HTTPBasicAuth de request.auth lo hace muy fácil!
Wallem89
26

Esto funcionó para mí:

access_token = #yourAccessTokenHere#

result = requests.post(url,
      headers={'Content-Type':'application/json',
               'Authorization': 'Bearer {}'.format(access_token)})
Edgar N
fuente
16

También puede establecer encabezados para toda la sesión:

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

with requests.Session() as s:

    s.headers.update(HEADERS)
    resp = s.get('http://example.com/')
Anton Tarasenko
fuente
4

Las solicitudes admiten de forma nativa la autenticación básica solo con parámetros de paso de usuario, no con tokens.

Si lo desea, puede agregar la siguiente clase para que las solicitudes admitan la autenticación básica basada en tokens:

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

Luego, para usarlo, ejecute la siguiente solicitud:

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

Una alternativa sería formular un encabezado personalizado en su lugar, tal como lo sugirieron otros usuarios aquí.

Amit Blum
fuente
3

fundé aquí, está bien conmigo para linkedin: https://auth0.com/docs/flows/guides/auth-code/call-api-auth-code, así que mi código con LinkedIn inicia sesión aquí:

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
fuente
2

Puedes probar algo como esto

r = requests.get(ENDPOINT, params=params, headers={'Authorization': 'Basic %s' %  API_KEY})
swatisinghi
fuente
0

Esto funcionó para mí:

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

Mi código usa un token generado por el usuario.

Reymond Joseph
fuente