(如何)可以发送带有request.OAuth2Session的(准备好的)请求?

时间:2019-04-12 15:36:37

标签: python python-3.x oauth-2.0 python-requests requests-oauthlib

运行以下命令时(显然是在用我们的API替换example.com的情况下)

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 个答案:

答案 0 :(得分:4)

OAuth2Session实现不会覆盖Session.prepare_request()Session.send()方法,只有Session.request()被专门化了。这是因为它以相同的方法处理自动刷新,需要发送更多请求。

为支持更改这些请求,该库提供了一个 compliance hooks 功能,该功能在过程中的特定点调用一个可以更改请求详细信息的钩子。自0.4.0版以来,OAuth2Session对象支持3个不同的挂钩:

  • access_token_response:在解析响应以提取令牌之前,从access token request传递了响应。
  • refresh_token_response:再次解析来自refresh token request的响应。
  • protected_request:传递了用于访问受保护资源的URL,标头和请求正文(因此,请求中应包含有效令牌)。

几个included compliance fixers使用这些钩子从某些提供程序的响应中添加缺少的元素,并在某些API偏离OAuth标准的令牌处理方式时更新传出的请求。

protected_request是一个有趣的钩子,因为它传递的数据与使用request.Request() / session.prepare_request() / session.send()模式时通常要更改的数据相同。在oauthlib客户端将令牌添加到该数据之前,您需要使用略有不同的包装来更改相同的请求数据。

也就是说,如果您不需要使用自动刷新或自己可以处理令牌到期,则可以直接访问OAuth2Sesson包装的oauthlib client。如果您已经fetched a token,则可以在准备之前使用以下方法签署您的请求:

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)

这直接使用了oauthlib客户端的add_token() method