OAuth 2 工作流程(转载)

OAuth 2 工作流程

介绍

以下部分提供了一些示例代码,演示了您可以与 requests-oauthlib 一起使用的一些可能的 OAuth2 流程。我们提供了四个示例:一个用于 OAuth2 RFC 定义的每种授权类型。这些授权类型(或工作流)是授权代码授权(或 Web 应用程序流)、隐式授权(或移动应用程序流)、资源所有者密码凭证授权(或更简洁地说,传统应用程序流)和客户端凭证授予(或后端应用程序流程)。

可用的工作流程

有四个核心工作流程:

  1. 授权码授予(Web 应用程序流)。
  2. 隐式授权(移动应用程序流)。
  3. 资源所有者密码凭证授予 (旧版应用程序流程)。
  4. 客户端凭据授予(后端应用程序流)。

网络应用程序流程

以下步骤概述了如何使用默认授权授予类型流程来获取访问令牌并获取受保护的资源。在此示例中,提供者是 Google,受保护的资源是用户的个人资料。

  1. 手动从您的 OAuth 提供商处获取凭据。至少您将需要一个client_id但可能还需要一个client_secret. 在此过程中,您可能还需要注册一个默认重定向 URI,以供您的应用程序使用。将这些内容保存在 Python 脚本中:
>>> client_id = r'your_client_id'
>>> client_secret = r'your_client_secret'
>>> redirect_uri = 'https://your.callback/uri'
  1. 通过重定向进行用户授权。首先,我们将从提供者提供的基本 URL 和先前获得的凭据创建一个授权 URL。此外,大多数提供商会要求您请求访问特定范围。在此示例中,我们将要求 Google 访问用户的电子邮件地址和用户个人资料。
# Note that these are Google specific scopes
>>> scope = ['https://www.googleapis.com/auth/userinfo.email',
             'https://www.googleapis.com/auth/userinfo.profile']
>>> oauth = OAuth2Session(client_id, redirect_uri=redirect_uri,
                          scope=scope)
>>> authorization_url, state = oauth.authorization_url(
        'https://accounts.google.com/o/oauth2/auth',
        # access_type and prompt are Google specific extra
        # parameters.
        access_type="offline", prompt="select_account")

>>> print 'Please go to %s and authorize access.' % authorization_url
>>> authorization_response = raw_input('Enter the full callback URL')
  1. 使用在用户授权期间获得的授权码从提供者处获取访问令牌。
>>> token = oauth.fetch_token(
        'https://accounts.google.com/o/oauth2/token',
        authorization_response=authorization_response,
        # Google specific extra parameter used for client
        # authentication
        client_secret=client_secret)
  1. 使用您刚刚获得的访问令牌访问受保护的资源。例如,获取用户个人资料信息。
>>> r = oauth.get('https://www.googleapis.com/oauth2/v1/userinfo')
>>> # Enjoy =)

移动应用流程

以下步骤概述了如何使用隐式代码授予类型流程来获取访问令牌。

  1. 您将需要以下设置。
>>> client_id = 'your_client_id'
>>> scopes = ['scope_1', 'scope_2']
>>> auth_url = 'https://your.oauth2/auth'
  1. 获取授权网址
>>> from oauthlib.oauth2 import MobileApplicationClient
>>> from requests_oauthlib import OAuth2Session
>>> oauth = OAuth2Session(client=MobileApplicationClient(client_id=client_id), scope=scopes)
>>> authorization_url, state = oauth.authorization_url(auth_url)
  1. 从提供程序获取访问令牌。
>>> response = oauth.get(authorization_url)
>>> oauth.token_from_fragment(response.url)

旧版应用程序流程

以下步骤概述了如何使用资源所有者密码凭据授予类型流程来获取访问令牌。

  1. 您将需要以下设置。client_secret是可选的,具体取决于提供者。
>>> client_id = 'your_client_id'
>>> client_secret = 'your_client_secret'
>>> username = 'your_username'
>>> password = 'your_password'
  1. 从提供程序获取访问令牌。
>>> from oauthlib.oauth2 import LegacyApplicationClient
>>> from requests_oauthlib import OAuth2Session
>>> oauth = OAuth2Session(client=LegacyApplicationClient(client_id=client_id))
>>> token = oauth.fetch_token(token_url='https://somesite.com/oauth2/token',
        username=username, password=password, client_id=client_id,
        client_secret=client_secret)

后端应用流程

以下步骤概述了如何使用资源所有者客户端凭据授予类型流程来获取访问令牌。

  1. 从您的 OAuth 提供商处获取凭据。至少你需要一个client_idand client_secret

    >>> client_id = 'your_client_id'
    >>> client_secret = 'your_client_secret'
    
  2. 从提供程序获取访问令牌。

    >>> from oauthlib.oauth2 import BackendApplicationClient
    >>> from requests_oauthlib import OAuth2Session
    >>> client = BackendApplicationClient(client_id=client_id)
    >>> oauth = OAuth2Session(client=client)
    >>> token = oauth.fetch_token(token_url='https://provider.com/oauth2/token', client_id=client_id,
            client_secret=client_secret)
    

    如果您的提供商要求您在 Basic Auth 标头中传递身份验证凭据,您可以这样做:

    >>> from oauthlib.oauth2 import BackendApplicationClient
    >>> from requests_oauthlib import OAuth2Session
    >>> from requests.auth import HTTPBasicAuth
    >>> auth = HTTPBasicAuth(client_id, client_secret)
    >>> client = BackendApplicationClient(client_id=client_id)
    >>> oauth = OAuth2Session(client=client)
    >>> token = oauth.fetch_token(token_url='https://provider.com/oauth2/token', auth=auth)
    

刷新令牌

某些提供商会为您refresh_token提供 access_token. 这些可用于直接获取新的访问令牌,而无需通过正常的 OAuth 工作流程。requests-oauthlib提供了三种获取刷新令牌的方法。所有这些都取决于您expires_in在令牌中指定的准确度。

expires_in是与访问和刷新令牌一起提供的凭据,指示从现在起访问令牌过期的秒数。通常,访问令牌会在一小时后过期,并且expires_in会是3600. 如果没有这个,就不可能requests-oauthlib知道令牌何时过期,因为由于令牌过期而导致请求失败的状态代码没有定义。

如果您对令牌刷新不感兴趣,请始终传递正值expires_in或完全忽略它。

(ALL) 定义令牌、令牌保护程序和所需的凭据

>>> token = {
...     'access_token': 'eswfld123kjhn1v5423',
...     'refresh_token': 'asdfkljh23490sdf',
...     'token_type': 'Bearer',
...     'expires_in': '-30',     # initially 3600, need to be updated by you
...  }
>>> client_id = r'foo'
>>> refresh_url = 'https://provider.com/token'
>>> protected_url = 'https://provider.com/secret'

>>> # most providers will ask you for extra credentials to be passed along
>>> # when refreshing tokens, usually for authentication purposes.
>>> extra = {
...     'client_id': client_id,
...     'client_secret': r'potato',
... }

>>> # After updating the token you will most likely want to save it.
>>> def token_saver(token):
...     # save token in database / session

(一)在每个请求上定义 Try-Catch TokenExpiredError

这是最基本的版本,当需要刷新但手动完成刷新时会引发错误。

>>> from requests_oauthlib import OAuth2Session
>>> from oauthlib.oauth2 import TokenExpiredError
>>> try:
...     client = OAuth2Session(client_id, token=token)
...     r = client.get(protected_url)
>>> except TokenExpiredError as e:
...     token = client.refresh_token(refresh_url, **extra)
...     token_saver(token)
>>> client = OAuth2Session(client_id, token=token)
>>> r = client.get(protected_url)

(二)定义自动令牌刷新自动但手动更新

这是自动刷新令牌的基本和方便刷新方法之间的中间,可以说是尴尬的,但保存新令牌是手动完成的。

>>> from requests_oauthlib import OAuth2Session, TokenUpdated
>>> try:
...     client = OAuth2Session(client_id, token=token,
...             auto_refresh_kwargs=extra, auto_refresh_url=refresh_url)
...     r = client.get(protected_url)
>>> except TokenUpdated as e:
...     token_saver(e.token)

TLS 客户端身份验证

要通过自签名或 CA 颁发的证书使用 TLS 客户端身份验证 (draft-ietf-oauth-mtls),请在令牌请求中传递证书并确保在请求中发送客户端 ID:

>>> oauth.fetch_token(token_url='https://somesite.com/oauth2/token',
...     include_client_id=True, cert=('test-client.pem', 'test-client-key.pem'))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值