Thư viện yêu cầu thư viện Python cách chuyển tiêu đề Ủy quyền bằng một mã thông báo


95

Tôi có một URI yêu cầu và một mã thông báo. Nếu tôi sử dụng:

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

v.v., tôi nhận được 200 và xem dữ liệu JSON tương ứng. Vì vậy, tôi đã cài đặt các yêu cầu và khi tôi cố gắng truy cập tài nguyên này, tôi nhận được 403 có thể là do tôi không biết cú pháp chính xác để chuyển mã thông báo đó. Bất cứ ai có thể giúp tôi tìm ra nó? Đây là những gì tôi có:

import sys,socket
import requests

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

Tôi đã thử:

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

Nhưng không có công việc nào trong số này.

Câu trả lời:


112

Trong python:

('<MY_TOKEN>')

tương đương với

'<MY_TOKEN>'

Và yêu cầu phiên dịch

('TOK', '<MY_TOKEN>')

Khi bạn muốn yêu cầu sử dụng Xác thực cơ bản và tạo tiêu đề ủy quyền như vậy:

'VE9LOjxNWV9UT0tFTj4K'

Đó là đại diện của base64 'TOK:<MY_TOKEN>'

Để vượt qua tiêu đề của riêng bạn, bạn chuyển vào từ điển như sau:

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

Traceback (lần gọi gần đây nhất): Tệp "<stdin>", dòng 1, trong <module> Tệp "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", dòng 55, trong yêu cầu trả lại nhận ('get', url, ** kwargs) Tệp" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api .py ", dòng 44, trong yêu cầu trả về session.request (method = method, url = url, ** kwargs) File" /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages /requests/sessions.py ", dòng 323, trong request prep = self.prepare_request (req)

@rebHelium bạn có thể GIST đó? Đó không phải là toàn bộ dấu vết ngăn xếp và không có dấu hiệu về những gì bạn thực sự đã thử.
Ian Stapleton Cordasco

Xin lỗi, Stack Overflow không cho phép tôi đăng toàn bộ đầu ra. Tôi đã làm chính xác như bạn đề nghị: r = requests.get ( 'bất cứ URL tôi có', tiêu đề = { 'Authorization': 'TOK: bất cứ điều gì tôi có mã thông báo'})

Không cần xin lỗi. Nó đã hoạt động? Bạn đã chấp nhận câu trả lời của tôi nhưng nó dường như đã gây ra một ngoại lệ cho bạn. Nếu bạn tạo ý chính, tôi có thể giúp bạn dễ dàng hơn là nói chuyện ở đây.
Ian Stapleton Cordasco

Sigma, tôi thực sự đã bỏ sót một chi tiết nhỏ trên mã của bạn gây ra lỗi. Mã thực tế là bí mật nên tôi không thể nói chính xác. Nhưng tôi sẽ đăng các câu hỏi bổ sung vì tôi muốn cải thiện kỹ năng Python của mình, nếu bạn muốn xem. Chúng là những câu hỏi rất đơn giản mà tôi chắc rằng bạn sẽ biết.

37

Tôi đã tìm kiếm một cái gì đó tương tự và bắt gặp điều này . Có vẻ như trong tùy chọn đầu tiên bạn đã đề cập

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

"auth" nhận hai tham số: tên người dùng và mật khẩu, vì vậy câu lệnh thực tế phải là

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

Trong trường hợp của tôi, không có mật khẩu, vì vậy tôi để trống tham số thứ hai trong trường auth như hình dưới đây:

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

Hy vọng điều này sẽ giúp ai đó :)


3
nếu bạn cố gắng r = requests.get('<MY_URI>',auth=('<MY_TOKEN>')), bạn sẽ nhận được TypeError: 'str' object is not callable. mà bối rối cho tôi trong một thời gian cho đến khi tôi tình cờ gặp này: /
aydow

Anserd của bạn đã giúp tôi nhưng chỉ sau khi đọc trong liên kết bạn cung cấp mà bạn đã truy cập. Làm việc với việc nhập HTTPBasicAuth từ request.auth khiến nó rất dễ dàng!
Wallem89

26

Điều này đã làm việc cho tôi:

access_token = #yourAccessTokenHere#

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

16

Bạn cũng có thể đặt tiêu đề cho toàn bộ phiên:

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

with requests.Session() as s:

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

4

Yêu cầu nguyên bản chỉ hỗ trợ xác thực cơ bản với thông số người dùng chuyển, không phải với mã thông báo.

Nếu bạn muốn, bạn có thể thêm lớp sau để yêu cầu xác thực cơ bản dựa trên mã thông báo hỗ trợ:

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

Sau đó, để sử dụng nó, hãy chạy yêu cầu sau:

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

Một giải pháp thay thế sẽ là tạo một tiêu đề tùy chỉnh, giống như những người dùng khác đã đề xuất ở đây.


3

tôi đã thành lập ở đây, đồng ý với tôi cho linkedin: https://auth0.com/docs/flows/guides/auth-code/call-api-auth-code vì vậy mã của tôi với đăng nhập linkedin ở đây:

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

Bạn có thể thử một cái gì đó như thế này

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

0

Điều này đã làm việc cho tôi:

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

Mã của tôi sử dụng mã thông báo do người dùng tạo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.