理解第三方授权访问的基本原理。
OAuth2 协议
OAuth2 是一个关于授权(Authorization)的开放网络标准协议。它的核心目的不是让第三方应用拿到用户的账号和密码,而是在用户同意后,给第三方应用发放一个临时令牌,让第三方应用可以在限定范围内访问用户资源。OAuth2 解决的是授权问题
它本身不直接解决“当前用户是谁”的认证问题。常见的“微信登录”“GitHub 登录”,通常是在 OAuth2 授权流程的基础上,再通过用户信息接口或
OpenID Connect 完成身份识别。
OAuth2 在客户端和资源所有者之间建立了一个授权层。资源所有者授权后,客户端不需要保存用户密码,而是使用获得的令牌访问资源。
⚠️ OAuth2.0 是 OAuth 协议的一个版本,但与 OAuth 1.0 不兼容。
典型授权场景
以“使用微信账号登录第三方应用”为例:
- 移动应用请求使用微信账号登录。
- 应用向微信申请必要的访问权限。
- 微信向用户展示授权确认弹窗。
- 用户同意后,微信先返回授权码
code。 - 应用使用
code向微信换取access_token。 - 应用使用
access_token获取授权范围内的用户信息。
access_token。第三方应用后续使用这个令牌访问资源,而不是直接使用用户的账号和密码。授权码模式
授权码模式是 OAuth2 中最常见、也最推荐的一种方式。
它的大致流程是:
- 客户端引导用户跳转到授权服务器。
- 用户在授权服务器上登录并确认授权。
- 授权服务器重定向回客户端,并携带授权码
code。 - 客户端使用
code、client_id、client_secret请求令牌。 - 授权服务器验证通过后,返回
access_token。 - 客户端使用
access_token请求资源服务器。 - 资源服务器验证令牌后,返回用户授权的数据。
这样设计的好处是:access_token 不会直接暴露在浏览器地址栏中,安全性比直接返回令牌更高。
获取令牌的方式
OAuth2 中常见的授权方式有:
- 授权码模式(Authorization Code)
- 授权码 + PKCE(Authorization Code with PKCE)
- 客户端凭证模式(Client Credentials)
- 密码模式(Password)
- 隐式模式(Implicit)
其中,授权码模式和授权码 + PKCE 是现在更常用、更推荐的方式。
不管是哪种授权方式,第三方应用申请令牌前,通常都需要先到授权系统备案,拿到应用身份信息:
client_id:客户端 ID,可以理解为应用的公开身份标识。client_secret:客户端密钥,只适合保存在服务端。
需要注意的是,浏览器单页应用、移动 App、小程序这类客户端无法安全保存 client_secret,不应该把密钥写进前端代码里。
这类场景更适合使用 PKCE 流程。
Access Token 和 Refresh Token
OAuth2 中常见的令牌有两种:
| Token | 作用 | 有效期 |
|---|---|---|
Access Token | 访问资源服务器 | 较短 |
Refresh Token | 换取新的访问令牌 | 较长 |
Access Token 用于访问用户授权范围内的资源,例如获取用户信息、读取头像、访问联系人等。
Refresh Token 用于在 Access Token 过期后,换取新的 Access Token,避免用户频繁重新授权。
一般流程是:
- 用户授权成功后,授权服务器返回
access_token和refresh_token。 - 客户端使用
access_token访问资源。 - 如果
access_token过期,客户端使用refresh_token请求新的访问令牌。 - 如果
refresh_token也过期,用户需要重新授权。
OAuth2 和 JWT 的区别
OAuth2 是一种授权协议,规定了第三方应用如何获取令牌、如何使用令牌访问资源。
JWT 是一种令牌格式,用来承载信息。
也就是说:
OAuth2关注的是“如何授权”。JWT关注的是“令牌长什么样、如何验证”。
OAuth2 里的 access_token 可以是 JWT,也可以是一段普通的随机字符串。