#python #python-3.x #oauth-2.0 #python-requests #requests-oauthlib
#python #python-3.x #oauth-2.0 #python-запросы #запросы-oauthlib
Вопрос:
При запуске следующего (при замене example.com
на наш API, очевидно)
req = Request('GET', 'https://example.com')
# client is a customized OAuth2Session
client.authorize(self.username, self.password, self.auth_key)
print(self.client.authorized) # True
следующее возвращает <Response [200]>
:
response = client.request(req.method, req.url)
Но это возвращает <Response [401]>
:
prepped = client.prepare_request(req)
response = client.send(prepped)
Как я могу повторно использовать исходный Request
объект при отправке его через OAuth2Session
?
Ответ №1:
OAuth2Session
Реализация не переопределяет методы Session.prepare_request()
or Session.send()
, только Session.request()
была специализированной. Это потому, что он обрабатывает автоматическое обновление тем же методом, требуя отправки большего количества запросов.
Для поддержки изменения этих запросов библиотека предлагает средство перехвата соответствия, где в определенные моменты процесса вызывается перехват, который может изменять детали запроса. Объект OAuth2Session, начиная с версии 0.4.0, поддерживает 3 разных перехвата:
access_token_response
: передан ответ на запрос токена доступа, прежде чем ответ будет проанализирован для извлечения токена.refresh_token_response
: передан ответ на запрос токена обновления, опять же, до того, как ответ будет проанализирован.protected_request
: передал URL, заголовки и тело запросов, используемых для доступа к защищенным ресурсам (таким образом, запрос, который должен включать действительный токен).
Несколько включенных исправителей соответствия используют эти перехваты для добавления недостающих элементов из ответов от определенных поставщиков и для обновления исходящих запросов, когда определенные API отклоняются от стандарта OAuth в отношении того, как они обрабатывают токены.
protected_request
здесь интересный хук, поскольку передаются те же данные, которые вы обычно хотели бы изменить при использовании шаблона request.Request()
/ session.prepare_request()
/ session.send()
. Вы можете изменить те же данные запроса в несколько иной упаковке, прежде чем клиент oauthlib сможет добавить токен к этим данным.
Тем не менее, если вам не нужно использовать автоматическое обновление или вы можете самостоятельно обрабатывать истечение срока действия токена, вы можете напрямую получить доступ к oauthlib
клиенту, который OAuth2Sesson
переносится. Если вы уже получили токен, вы можете подписать свой запрос перед подготовкой с помощью:
from oauthlib.oauth2 import TokenExpiredError
req = Request('GET', 'https://example.com')
try:
req.url, req.headers, req.data = client._client.add_token(
req.url, http_method=req.method, body=req.data, headers=req.headers
)
except TokenExpiredError:
# handle token expiration
pass
else:
prepped = client.prepare_request(req)
response = client.send(prepped)
При этом напрямую используется add_token()
метод клиента oauthlib.
Комментарии:
1. Имея подготовленный запрос, подобный этому:
req = requests.Request('GET', BASE_URL, params=params)
как я могу его затем отправить? Я использовалdir(req)
, но, похоже, у него нетsend
метода. Обязательно ли мне передавать его черезSession
объект? Это то, чтоrequests.get
/requests.post
делать за кулисами? Они создают сеанс и передают подготовленный запрос в сеанс?2. @M.Ionut: да, вы должны передать подготовленный запрос
session.request()
. Это то, что делает пример кода в моем ответе (client
является экземпляромOAuth2Session
here , который является подклассомSession
).3. @M.Ionut: под прикрытием
Session.request()
создаетRequest
экземпляр, используетSession.prepare()
его для превращения в aPreparedRequest
, затем передает последнийSession.send()
.Session.request()
это чтоSession.get()
/Session.post()
и т.д. все откладывается на.