一、授权码和访问令牌的意义
1. 授权码(Authorization Code)
-
作用:授权码是一个短期有效的临时凭证,用于换取访问令牌。
-
特点:
- 有效期短(通常几分钟)。
- 只能使用一次。
- 通过前端(浏览器)传递,但不包含敏感信息(如用户凭证)。
-
意义:
- 避免直接传递访问令牌,减少令牌泄露的风险。
- 提供额外的安全层,确保只有合法的客户端可以获取访问令牌。
2. 访问令牌(Access Token)
-
作用:访问令牌是客户端访问资源服务器的凭证。
-
特点:
- 有效期较长(通常几小时到几天)。
- 包含用户的权限信息(如作用域)。
- 通过后端传递,避免暴露给前端。
-
意义:
- 作为客户端访问资源的凭证,避免直接使用用户凭证(如用户名和密码)。
- 支持细粒度的权限控制(通过作用域)。
二、为什么要分两层(授权码和访问令牌)
1. 安全性
- 授权码:通过前端(浏览器)传递,但不包含敏感信息。即使授权码被截获,攻击者也无法直接使用它访问资源。
- 访问令牌:通过后端传递,避免暴露给前端,减少令牌泄露的风险。
2. 灵活性
- 授权码:用于在客户端和授权服务器之间建立信任关系。
- 访问令牌:用于客户端和资源服务器之间的交互,支持多种令牌类型(如 JWT)。
3. 防止中间人攻击
- 授权码模式要求客户端在获取访问令牌时提供客户端密钥(Client Secret),确保只有合法的客户端可以完成授权流程。
三、授权码模式的工作原理
以下是 OAuth 2.0 授权码模式的详细工作流程:
1. 用户访问客户端
- 用户访问客户端应用(如一个博客网站)。
- 客户端需要访问用户的资源(如 Google 相册)。
2. 重定向到授权服务器
-
客户端将用户重定向到授权服务器的授权端点(Authorization Endpoint)。
-
重定向 URL 包含以下参数:
client_id:客户端 ID。redirect_uri:重定向 URI。response_type=code:请求授权码。scope:请求的权限范围(如read)。state:随机字符串,用于防止 CSRF 攻击。
示例:
https://auth.example.com/oauth/authorize?
client_id=client-app&
redirect_uri=http://client-app.com/callback&
response_type=code&
scope=read&
state=abc123
3. 用户登录并授权
- 用户在授权服务器上登录并同意客户端的请求。
- 授权服务器生成一个授权码(Authorization Code)并重定向回客户端。
示例:
http://client-app.com/callback?code=xyz789&state=abc123
4. 客户端获取访问令牌
-
客户端使用授权码向授权服务器的令牌端点(Token Endpoint)请求访问令牌。
-
请求包含以下参数:
grant_type=authorization_code:授权类型为授权码。code:授权码。redirect_uri:重定向 URI。client_id:客户端 ID。client_secret:客户端密钥。
示例:
POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=xyz789&
redirect_uri=http://client-app.com/callback&
client_id=client-app&
client_secret=secret
5. 授权服务器返回访问令牌
- 授权服务器验证授权码和客户端信息,返回访问令牌(Access Token)和刷新令牌(Refresh Token)。
示例:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def456"
}
6. 客户端访问资源服务器
- 客户端使用访问令牌访问资源服务器。
- 资源服务器验证访问令牌并返回请求的资源。
示例:
GET /api/resource HTTP/1.1
Host: resource.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
四、授权码模式的分层设计原理
1. 前端通道(Front Channel)
- 作用:用户通过浏览器与授权服务器交互。
- 传递内容:授权码(Authorization Code)。
- 安全性:授权码不包含敏感信息,即使被截获也无法直接使用。
2. 后端通道(Back Channel)
- 作用:客户端与授权服务器直接交互。
- 传递内容:访问令牌(Access Token)。
- 安全性:访问令牌通过后端传递,避免暴露给前端。
- 授权码:用于在用户授权后,客户端从授权服务器获取访问令牌的临时凭证。
- 访问令牌:用于客户端访问资源服务器的凭证。
- 分层设计:通过前端通道传递授权码,后端通道传递访问令牌,提高安全性。
- 授权码模式:是 OAuth 2.0 中最安全的授权模式,适用于 Web 应用。