OAuth 1 工作流
使用 OAuth 时,您将被迫经历几个步骤。下面是使用 HMAC-SHA1 签名请求的最常见 OAuth 工作流的示例,其中签名在 Authorization 标头中提供。
此示例假定一个交互式提示,这对于演示来说很好,但在实践中,您可能将使用 Web 应用程序(这使得授权不那么尴尬,因为您可以简单地重定向)。
本指南将展示执行 OAuth1 工作流的两种方法。一种使用身份验证助手 OAuth1,另一种使用 OAuth1Session。后者通常更方便,并且需要的代码更少。
工作流示例,展示如何同时使用 OAuth1 和 OAuth1Session
使用 OAuth 提供商(例如 Google、Twitter)手动注册客户端以获取一组客户端凭据。通常是客户端密钥和密钥。客户端有时可能称为使用者。例如
>>> # Using OAuth1Session
>>> from requests_oauthlib import OAuth1Session
>>> # Using OAuth1 auth helper
>>> import requests
>>> from requests_oauthlib import OAuth1
>>> client_key = '...'
>>> client_secret = '...'
获取一个请求令牌,它将在下一步中识别您(客户端)。在此阶段,您只需要您的客户端密钥和密钥。
>>> request_token_url = 'https://api.twitter.com/oauth/request_token'
>>> # Using OAuth1Session
>>> oauth = OAuth1Session(client_key, client_secret=client_secret)
>>> fetch_response = oauth.fetch_request_token(request_token_url)
{
"oauth_token": "Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik",
"oauth_token_secret": "Kd75W4OQfb2oJTV0vzGzeXftVAwgMnEK9MumzYcM"
}
>>> resource_owner_key = fetch_response.get('oauth_token')
>>> resource_owner_secret = fetch_response.get('oauth_token_secret')
>>> # Using OAuth1 auth helper
>>> oauth = OAuth1(client_key, client_secret=client_secret)
>>> r = requests.post(url=request_token_url, auth=oauth)
>>> r.content
"oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik&oauth_token_secret=Kd75W4OQfb2oJTV0vzGzeXftVAwgMnEK9MumzYcM"
>>> from urlparse import parse_qs
>>> credentials = parse_qs(r.content)
>>> resource_owner_key = credentials.get('oauth_token')[0]
>>> resource_owner_secret = credentials.get('oauth_token_secret')[0]
从用户(资源所有者)处获得授权以访问其受保护的资源(图像、推文等)。这通常通过将用户重定向到特定 URL 来完成,您将请求令牌作为查询参数添加到该 URL。请注意,并非所有服务都会给您验证器,即使它们应该这样做。此外,此处给出的 oauth_token 将与前一步中的相同。
>>> base_authorization_url = 'https://api.twitter.com/oauth/authorize'
>>> # Using OAuth1Session
>>> authorization_url = oauth.authorization_url(base_authorization_url)
>>> print('Please go here and authorize,', authorization_url)
>>> redirect_response = input('Paste the full redirect URL here: ')
>>> oauth_response = oauth.parse_authorization_response(redirect_response)
{
"oauth_token": "Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik",
"oauth_verifier": "sdflk3450FASDLJasd2349dfs"
}
>>> verifier = oauth_response.get('oauth_verifier')
>>> # Using OAuth1 auth helper
>>> authorize_url = base_authorization_url + '?oauth_token='
>>> authorize_url = authorize_url + resource_owner_key
>>> print('Please go here and authorize,', authorize_url)
>>> verifier = input('Please input the verifier')
从 OAuth 提供商处获取访问令牌。保存此令牌,因为它可以在以后重新使用。在此步骤中,我们将重新使用迄今为止获得的大多数凭据。
>>> access_token_url = 'https://api.twitter.com/oauth/access_token'
>>> # Using OAuth1Session
>>> oauth = OAuth1Session(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier)
>>> oauth_tokens = oauth.fetch_access_token(access_token_url)
{
"oauth_token": "6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY",
"oauth_token_secret": "2EEfA6BG3ly3sR3RjE0IBSnlQu4ZrUzPiYKmrkVU"
}
>>> resource_owner_key = oauth_tokens.get('oauth_token')
>>> resource_owner_secret = oauth_tokens.get('oauth_token_secret')
>>> # Using OAuth1 auth helper
>>> oauth = OAuth1(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier)
>>> r = requests.post(url=access_token_url, auth=oauth)
>>> r.content
"oauth_token=6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY&oauth_token_secret=2EEfA6BG3ly3sR3RjE0IBSnlQu4ZrUzPiYKmrkVU"
>>> credentials = parse_qs(r.content)
>>> resource_owner_key = credentials.get('oauth_token')[0]
>>> resource_owner_secret = credentials.get('oauth_token_secret')[0]
访问受保护的资源。OAuth1 访问令牌通常不会过期,并且可以在用户或您自己撤销之前重新使用。
>>> protected_url = 'https://api.twitter.com/1/account/settings.json'
>>> # Using OAuth1Session
>>> oauth = OAuth1Session(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret)
>>> r = oauth.get(protected_url)
>>> # Using OAuth1 auth helper
>>> oauth = OAuth1(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret)
>>> r = requests.get(url=protected_url, auth=oauth)
签名放置 - 标头、查询或正文?
OAuth 有多种形式,因此让我们来看一些不同的形式
import requests
from requests_oauthlib import OAuth1
url = 'https://api.twitter.com/1/account/settings.json'
client_key = '...'
client_secret = '...'
resource_owner_key = '...'
resource_owner_secret = '...'
标头签名(推荐)
headeroauth = OAuth1(client_key, client_secret,
resource_owner_key, resource_owner_secret,
signature_type='auth_header')
r = requests.get(url, auth=headeroauth)
查询签名
queryoauth = OAuth1(client_key, client_secret,
resource_owner_key, resource_owner_secret,
signature_type='query')
r = requests.get(url, auth=queryoauth)
正文签名
bodyoauth = OAuth1(client_key, client_secret,
resource_owner_key, resource_owner_secret,
signature_type='body')
r = requests.post(url, auth=bodyoauth)
签名类型 - HMAC(最常见)、RSA、纯文本
OAuth1 默认使用 HMAC,可以在前几部分中找到示例。
纯文本使用与 HMAC 相同的凭据,在使用它时您需要做的唯一更改是将 signature_type=’PLAINTEXT’ 添加到 OAuth1 构造函数
headeroauth = OAuth1(client_key, client_secret,
resource_owner_key, resource_owner_secret,
signature_method='PLAINTEXT')
RSA 的不同之处在于它不使用 client_secret 也不使用 resource_owner_secret。它使用公钥和私钥。在客户端注册期间将公钥提供给 OAuth 提供商。私钥用于对请求进行签名。前一部分可以总结为
key = open("your_rsa_key.pem").read()
queryoauth = OAuth1(client_key, signature_method=SIGNATURE_RSA,
rsa_key=key, signature_type='query')
headeroauth = OAuth1(client_key, signature_method=SIGNATURE_RSA,
rsa_key=key, signature_type='auth_header')
bodyoauth = OAuth1(client_key, signature_method=SIGNATURE_RSA,
rsa_key=key, signature_type='body')