0%

OAuth20

OAuth2.0
OAuth 2.0 是一个广泛使用的授权框架,允许用户授权第三方应用访问其在服务提供者(如 Google、Facebook、GitHub 等)上的受保护资源,而无需分享其用户名和密码。下面是 OAuth 2.0 的基本授权流程,我们以一个典型的 “用户通过 Google 账户登录第三方应用” 的场景为例:

OAuth 2.0 的授权流程(典型授权码授权流程)

假设你想使用一个第三方应用(例如:一个待开发的任务管理应用),它要求访问你的 Google 日历,OAuth 2.0 就是用来处理这类授权的协议。

流程步骤:

1. 用户发起授权请求

用户访问第三方应用的某个功能,第三方应用请求获取访问用户在 Google 上的某些数据(例如:Google 日历数据)。为了访问这些数据,第三方应用必须首先获得授权。

  • 第三方应用会将用户重定向到 Google 的授权服务器。
  • 重定向的 URL 中包含必要的参数:
    • client_id:第三方应用的标识符,用于区分不同的客户端。
    • redirect_uri:用户授权后,Google 重定向到的回调地址。
    • response_type:通常是 code,表示请求授权码。
    • scope:请求的权限范围,决定了第三方应用可以访问哪些用户资源(如 https://www.googleapis.com/auth/calendar)。
    • state:防止跨站请求伪造(CSRF)攻击的随机字符串。

请求示例:

1
2
3
4
5
6
GET https://accounts.google.com/o/oauth2/v2/auth?
client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/oauth2callback
&response_type=code
&scope=https://www.googleapis.com/auth/calendar
&state=xyz123

2. 用户授权

  • 用户被引导到 Google 的授权页面,在该页面上,Google 会询问用户是否允许第三方应用访问其 Google 日历。
  • 用户可以选择“允许”或“拒绝”授权。如果用户允许,Google 会将用户重定向回第三方应用指定的 redirect_uri,并附带一个授权码(Authorization Code)。

重定向示例:

1
2
3
https://yourapp.com/oauth2callback?
code=AUTHORIZATION_CODE
&state=xyz123

3. 客户端请求访问令牌

  • 第三方应用(客户端)收到授权码后,接着通过向 Google 的授权服务器发起请求来交换访问令牌(Access Token)。
  • 这个请求需要包含以下信息:
    • client_id:第三方应用的标识符。
    • client_secret:第三方应用的密钥,用于验证其身份。
    • code:从重定向中获得的授权码。
    • redirect_uri:必须与授权请求时提供的重定向 URI 完全一致。
    • grant_type:通常是 authorization_code,表示通过授权码换取令牌。

请求示例:

1
2
3
4
5
6
7
8
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded

client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&code=AUTHORIZATION_CODE
&redirect_uri=https://yourapp.com/oauth2callback
&grant_type=authorization_code

4. 授权服务器返回访问令牌

  • Google 的授权服务器会验证请求,并返回一个包含访问令牌的响应。访问令牌可以用于访问 Google API,获得用户授权的资源(如 Google 日历数据)。
  • 除了 access_token,响应中通常还会包含 expires_in(令牌的有效期,通常是一个小时)和 refresh_token(刷新令牌,用于获取新的访问令牌)。

响应示例:

1
2
3
4
5
6
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN"
}

5. 客户端使用访问令牌访问资源

  • 第三方应用可以使用获得的 access_token 来访问用户授权的资源(如 Google 日历数据)。
  • 在每个请求中,客户端将 access_token 作为 HTTP 请求头的一部分发送给 Google API。

请求示例:

1
2
GET https://www.googleapis.com/calendar/v3/calendars/primary/events
Authorization: Bearer ACCESS_TOKEN

Google 会验证令牌,如果令牌有效,API 就会返回用户的日历数据。

6. 令牌过期与刷新

  • 访问令牌有时效性,一旦过期,客户端可以使用 refresh_token 来获取一个新的访问令牌,而无需再次请求用户授权。
  • 使用 refresh_token 刷新访问令牌的请求格式如下:
1
2
3
4
5
6
7
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded

client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&refresh_token=REFRESH_TOKEN
&grant_type=refresh_token

响应示例:

1
2
3
4
5
{
"access_token": "NEW_ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600
}

总结流程

  1. 用户请求授权:第三方应用将用户重定向到授权服务器(如 Google)以请求授权。
  2. 用户授权:用户在授权页面同意授权后,授权服务器返回授权码。
  3. 交换访问令牌:第三方应用使用授权码请求访问令牌。
  4. 获取用户数据:第三方应用使用访问令牌请求用户数据。
  5. 令牌刷新(可选):访问令牌过期时,第三方应用使用刷新令牌获取新的访问令牌。

其他授权方式

除了授权码授权(Authorization Code Grant)外,OAuth 2.0 还定义了其他授权方式,如:

  • 简化授权流程(Implicit Grant):用于浏览器端应用,令牌直接通过 URL 传递。
  • 客户端凭证授权(Client Credentials Grant):用于机器对机器的通信,没有用户参与。
  • 密码授权(Resource Owner Password Credentials Grant):用户提供用户名和密码,客户端直接获取访问令牌,不推荐用于公共应用。

这些不同的授权方式适应不同的场景,但授权码授权是最常用、最安全的一种。

总结:

OAuth 2.0 的流程包括授权请求、用户授权、访问令牌交换和资源访问等多个步骤,确保了第三方应用能够安全地访问用户的受保护资源,而不需要直接获取用户的凭证。