OAuth2.0 - 授权码模式

668 阅读4分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

授权码模式

授权码模式用于获取访问令牌和刷新令牌,并针对客户端进行了优化。由于这是基于重定向的流程,因此客户端必须能够与资源所有者的用户代理(通常是 Web 浏览器)交互,并能够从授权服务器接收传入请求(通过重定向)。

流程

     +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)

(A)用户访问客户端,客户端将用户导向认证服务器。

客户端通过按application/x-www-form-urlencoded格式向授权端点URI的查询部分添加下列参数构造请求URI

参数说明:

参数参数说明是否必填备注
response_type授权类型必填此处的值必须为code
client_id客户端的ID必填客户端申请时候生成的client_id,有时候会用app_id
redirect_uri重定向URI必填客户端注册时候填写的redirect_uri
scope申请的权限范围可选项
state任意值建议必填认证服务器会原样返回,用于抵制CSRF(跨站请求伪造)攻击

客户端使用HTTP重定向响应向构造的URI定向资源所有者,或者通过经由用户代理至该URI的其他可用方法。

GET /authorize
?response_type=code
&client_id=s6BhdRkqt3
&state=xyz
&redirect_uri=https://client.example.com/cb
HTTP/1.1
Host: server.example.com

授权服务器验证该请求,确保所有需要的参数已提交且有效。如果请求是有效的,授权服务器对资源所有者进行身份验证并获得授权决定(通过询问资源所有者或通过经由其他方式确定批准)。

当确定决定后,授权服务器使用HTTP重定向响应向提供的客户端重定向URI定向用户代理,或者通过经由用户代理至该URI的其他可行方法。

(B)授权服务器对用户的身份验证,并确定用户是否给予客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的重定向URIredirection URI),同时附上一个授权码。

服务器回应客户端的URI

参数说明:

参数参数说明是否必填备注
code授权码必填授权服务器生成的授权码。授权码必须在颁发后很快过期以减小泄露风险。推荐的最长的授权码生命周期是10分钟。客户端不能使用授权码超过一次。如果一个授权码被使用一次以上,授权服务器必须拒绝该请求并应该撤销(如可能)先前发出的基于该授权码的所有令牌。授权码与客户端标识和重定向URI绑定。
state同步骤(A)的state必填原样返回客户端传的该参数的值。
https://client.example.com/cb
?code=SplxlOBeZQQYbYS6WxSbIA
&state=xxx

(D)客户端收到授权码,附上早先的重定向URI,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

步骤:客户端向认证服务器申请令牌

参数参数说明是否必填备注
client_id客户端的ID必填客户端申请时候生成的client_id,有时候会用app_id
grant_type授权模式必填此处的值固定authorization_code
code同步骤(C)的code必填认证服务器会原样返回,用于抵制CSRF(跨站请求伪造)攻击
redirect_uri重定向URI必填必须与步骤(A)中的该参数值保持一致。
https://www.example.com/v1/oauth/token
?client_id=CLIENT_ID
&grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=CALLBACK_URL

授权服务器必须:

  • 若包括了客户端身份验证,验证客户端身份,
  • 确保验证授权码是有效的
  • 确保给出了redirect_uri参数

(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

响应(D)步骤的数据

{
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
 }
参数参数说明是否必填备注
access_token访问令牌必填
token_type令牌类型必填该值大小写不敏感
expires_in过期时间,单位为秒。可选如果省略该参数,必须其他方式设置过期时间。
refresh_token更新令牌可选用来获取下一次的访问令牌
scope权限范围可选如果与客户端申请的范围一致,此项可省略。

使用场景

  • 授权码模式是最常见的一种授权模式,在oauth2.0内是最安全和最完善的。
  • 适用于所有有Server端的应用,如Web站点、有Server端的手机客户端。 
  • 可以得到较长期限授权。