简介
OAuth 2是一个授权框架,它允许应用程序--如Facebook、GitHub和DigitalOcean--获得对HTTp服务上的用户帐户的有限访问权限。它的工作方式是将用户身份验证委托给托管用户帐户的服务,并授权第三方应用程序访问该用户帐户。OAuth 2为Web和桌面应用程序以及移动设备提供授权流。
本信息指南面向应用程序开发人员,概述了OAuth 2的角色、授权授权类型、用例和流程。
OAuth角色
OAuth定义了四个角色:
- 资源所有者 :资源所有者是授权AN_APPLICATION_访问其账户的_USER_。应用程序对用户帐户的访问权限限于授予的授权范围(例如,读或写访问权限)
- 客户端 :客户端是要访问该用户的S账号的_APPLICATION_,必须经过用户授权,并通过接口进行验证。
- 资源服务器 :资源服务器托管受保护的用户账号。
- 授权服务器 :授权服务器验证_USER_的身份,然后向_APPLICATION_颁发访问令牌。
从应用程序开发人员的角度来看,服务的API同时履行资源和授权服务器角色。我们将这两个角色组合起来称为_Service_或_API_Role。
抽象协议流程
现在您已经了解了OAuth角色是什么,让我们看一看它们通常如何相互交互的图:
以下是对图中步骤的更详细说明:
应用程序_请求授权从_用户_访问服务资源 2.如果用户授权了该请求,则应用程序将收到授权授权 3.应用程序通过提供其自身身份的认证和授权授权来向授权服务器(API)请求访问令牌 4.如果应用程序身份通过认证并且授权授权有效,则授权服务器(API)向应用程序下发访问令牌。授权已完成。 5.应用程序向资源服务器(API)请求资源并提供用于身份验证的访问令牌 6.如果访问令牌有效,则资源服务器_(API)将资源提供给_应用程序_
根据使用的授权授权类型的不同,此过程的实际流程会有所不同,但这是大体思路。我们将在后面的章节中探索不同的资助类型。
应用注册
在将OAuth与您的应用程序一起使用之前,您必须向该服务注册您的应用程序。这是通过在服务网站的开发者 或** API** 部分中的注册表完成的,在那里您将提供以下信息(可能还包括您的应用程序的详细信息):
- 应用程序名称
- 申请网站
- 重定向URI或回调URL
重定向URI是在用户授权(或拒绝)您的应用程序后,服务将重定向用户的位置,因此也是处理授权码或访问令牌的应用程序部分。
Client ID和Client Secret
一旦您的应用程序被注册,服务将以_客户端标识符和_客户端秘密的形式颁发_客户端凭据。客户端ID是一个公开的字符串,服务API使用它来标识应用程序,它还用于构建呈现给用户的授权URL。客户端秘密用于在应用程序请求访问用户帐户时向服务API验证应用程序的身份,并且必须在应用程序和API之间保密。
授权授权
在前面概述的抽象协议流程中,前四个步骤包括获取授权授权和访问令牌。授权授权类型取决于应用程序请求授权的方法,以及API支持的授权类型。OAuth 2定义了三种主要授权类型,每种类型在不同情况下都很有用:
- 授权码 :与服务器端应用程序配合使用
- 客户端凭据 :与有API访问权限的应用程序配合使用
- 设备代码 :用于没有浏览器或有输入限制的设备
<$>[警告] 警告 :OAUTH框架规定了两种额外的授权类型:** 隐式Flow** 类型和** 密码Grant** 类型]。然而,这两种赠款类型都被认为是不安全的,不再推荐使用。 <$>
在接下来的部分中,我们将更详细地描述授权类型、它们的用例和流程。
授权类型:授权码
授权码 授权类型是最常用的,因为它针对_服务端应用程序进行了优化,源代码不公开,并且可以维护_客户端Secret_机密性。这是一个基于重定向的流,这意味着应用程序必须能够与用户代理(即用户的Web浏览器)交互,并接收通过用户代理路由的API授权码。
现在我们将描述授权码流程:
第一步-授权码链接
首先,向用户提供如下所示的授权码链接:
1https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
以下是对此示例链接的组件的说明:
*https://cloud.digitalocean.com/v1/oauth/authorize :接口授权端点
- CLIENT_ID=CLIENT_ID :应用的_CLIENT ID_(接口如何标识应用)
- REDIRECT_URI=CALLBACK_URL :授权码授予后,服务重定向用户代理
- RESPONSE_TYPE=CODE :指定您的应用程序正在请求授权代码授予
- Scope=Read :指定应用程序请求的访问级别
第二步-用户授权申请
当用户单击该链接时,他们必须首先登录到该服务以验证其身份(除非他们已经登录)。然后,服务将提示他们授权或拒绝应用程序对其帐户的访问。以下是授权应用程序提示示例:
这张截图是DigitalOcean的授权屏幕,它表明Thedroetbook App 正在请求授权** 读取** 访问[email protected]
的账号。
第三步-应用收到授权码
如果用户点击授权应用 ,服务会将用户代理重定向到客户端注册时指定的应用程序重定向URI,以及_授权码_。重定向如下所示(假设应用程序是dropetbook.com
):
1https://dropletbook.com/callback?code=AUTHORIZATION_CODE
Step 4 -应用请求访问令牌
应用程序向API令牌端点传递授权码和身份验证详细信息(包括_CLIENT SECRET_),从而向API请求访问令牌。下面是对DigitalOcean的令牌端点的POST
请求示例:
1https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
步骤5-应用程序接收访问令牌
如果授权有效,API将向应用程序发送包含访问令牌(以及可选的刷新令牌)的响应。整个回应将如下所示:
1{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{"name":"Mark E. Mark","email":"[email protected]"}}
现在,应用程序已获得授权。它可以使用令牌通过服务API访问用户的帐户,但限于访问范围,直到令牌过期或被撤销。如果发布了刷新令牌,则在原始令牌已过期的情况下,该令牌可用于请求新的访问令牌。
代码交换证明密钥注意事项
如果公共客户端正在使用授权码授权类型,则授权码有可能被截获。代码交换的_Profect密钥(或_PKCE_,发音类似于)是授权码流的扩展,有助于缓解此类攻击。
PKCE扩展涉及客户端为每个授权请求创建和记录一个秘密密钥-称为_code verifier_。然后,客户端将代码验证器转换为_code challenge_,然后将此代码challenge和转换方法发送到同一授权请求中的授权端点。
授权端点记录代码质询和转换方法,并使用授权代码进行响应,如前所述。然后客户端发送访问令牌请求,其中包括它最初生成的代码验证器。
授权服务器收到代码验证器后,使用客户端首先共享的转换方法将其转换为代码挑战。如果客户端发送的来自代码验证器的代码质询与授权服务器最初记录的代码质询不匹配,则授权服务器将拒绝客户端访问。
建议每个客户端使用PKCE扩展以提高安全性。
授权类型:客户端凭证
客户端凭据 授权类型为应用程序提供了访问其自身服务帐户的方式。例如,当应用程序想要更新其注册的描述或重定向URI,或通过API访问存储在其服务帐户中的其他数据时,这可能是有用的。
客户端凭证流程
应用程序通过将其凭据、其客户端ID和客户端机密发送到授权服务器来请求访问令牌。示例POST
请求可能如下所示:
1https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
如果应用程序凭据签出,则授权服务器向应用程序返回访问令牌。现在,应用程序被授权使用自己的帐户。
<$>[注]
注意 :DigitalOcean目前不支持客户端凭证授权类型,因此链接指向虚构的授权服务器oauth.example.com
。
<$>
授权类型:设备编码
设备码 授权类型为没有浏览器或输入有限的设备提供了一种获取访问令牌和访问用户帐户的方式。此授权类型的目的是使用户能够更轻松地授权此类设备上的应用程序访问其帐户。例如,如果用户想要登录到没有典型键盘输入的设备上的视频流应用程序,例如智能电视或视频游戏机,这可能是有用的。
设备代码流
用户在他们的无浏览器或输入受限的设备上启动应用程序,例如电视机或机顶盒。应用程序向a_Device授权端点_提交POST
请求。
设备代码POST
请求示例可能如下所示:
1POST https://oauth.example.com/device
2
3client_id=CLIENT_id
设备授权端点与身份验证服务器不同,因为设备授权端点实际上并不对设备进行身份验证。相反,它返回一个唯一的_device code_,用于标识设备;一个_user code_,用户可以在更容易进行身份验证的机器上输入,如笔记本电脑或移动终端;以及用户应该访问的URL,以输入用户代码并验证其设备。
以下是来自设备授权端点的示例响应:
1{
2 "device_code": "IO2RUI3SAH0IQuESHAEBAeYOO8UPAI",
3 "user_code": "RSIK-KRAM",
4 "verification_uri": "https://example.okta.com/device",
5 "interval": 10,
6 "expires_in": 1600
7}
请注意,设备代码也可以是阅读器可以在移动设备上扫描的二维码。
然后,用户在指定的URL处输入用户代码并登录到他们的帐户。然后,他们会看到一个同意屏幕,在那里他们可以授权设备访问他们的账户。
当用户访问验证URL并输入他们的代码时,设备将轮询访问端点,直到它返回错误或身份验证令牌。如果设备轮询太频繁(low_down
错误),如果用户尚未批准或拒绝请求(AUTHORIZATION_PENDIN
错误),如果用户拒绝请求(ACCESS_DENIED
错误),或者如果令牌已过期(EXPIRED_TOKEN
错误),则访问端点将返回错误。
但是,如果用户批准请求,则访问端点将返回身份验证令牌。
<$>[备注]
注 :再次声明,DigitalOcean目前不支持设备代码授权类型,因此本例中的链接指向一个虚构的授权服务器,地址为oauth.example.com
。
<$>
访问令牌使用示例
一旦应用程序有了访问令牌,它就可以使用令牌通过API访问用户的帐户,但限于访问范围,直到令牌过期或被撤销。
以下是一个使用curl
的API请求示例。请注意,它包括访问令牌:
1curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"
假设访问令牌有效,则API会根据其API规范处理请求。如果访问令牌过期或无效,接口将返回INVALID_REQUEST
错误。
刷新令牌流
访问令牌过期后,使用该令牌向接口请求会导致令牌无效错误
。此时,如果在颁发原始访问令牌时包括刷新令牌,则可以使用它向授权服务器请求新的访问令牌。
下面是一个POST
请求示例,使用刷新令牌来获取新的访问令牌:
1https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN
结论
通过遵循本指南,您将了解OAuth 2如何工作,以及何时应该使用特定的授权流。
如果您想了解更多关于OAuth 2的信息,请查看这些有价值的资源:
- 如何以用户或Developer身份对DigitalOcean使用OAUTH身份验证
- 如何使用DigitalOcean接口v2
- DigitalOcean OAuth接口参考Documentation
- OAuth 2.0授权Framework