OAuth2 授权流程详解
OAuth2 是一种开放标准授权协议,用于让用户授权第三方应用访问其资源,而无需透露用户名和密码。
🔐 OAuth2 解决了什么问题?
- 不暴露密码给第三方应用
- 支持多种客户端(Web、App、服务间调用)
- 用户可随时撤销授权
- 实现统一登录(如 GitHub 登录、Google 登录)
🔁 授权码模式(最常用)
前端 → GitHub 授权 → GitHub 重定向带 code → 后端换取 access_token → 获取用户信息
授权步骤详解
- 用户点击“GitHub 登录”按钮,跳转 GitHub 授权页面
- 用户同意授权后,GitHub 重定向回你的 redirect_uri,附带临时 code
- 后端接收到 code 后,请求 GitHub 换取 access_token
- 后端再使用 access_token 请求 GitHub API 获取用户信息
✅ OAuth2 四种模式对比
模式 | 适用场景 | 特点 |
---|---|---|
授权码模式 | Web 应用 | 最安全,需后端参与 |
简化模式 | 纯前端单页应用 | 已不推荐使用 |
密码模式 | 内部系统、信任客户端 | 简单但不安全,不推荐 |
客户端模式 | 服务对服务通信 | 无用户参与 |
🧩 实战示例:GitHub OAuth 登录流程
1️⃣ 前端跳转授权页面
const clientId = "YOUR_CLIENT_ID";
window.location.href = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=http://localhost:3000/oauth/callback`;
2️⃣ 后端用 code 换取 token(Node.js)
const axios = require("axios");
const getAccessToken = async (code) => {
const res = await axios.post("https://github.com/login/oauth/access_token", {
client_id: "YOUR_CLIENT_ID",
client_secret: "YOUR_CLIENT_SECRET",
code,
}, {
headers: { Accept: "application/json" }
});
return res.data.access_token;
};
3️⃣ 用 token 获取用户信息
const res = await axios.get("https://api.github.com/user", {
headers: { Authorization: `token ${access_token}` }
});
console.log(res.data.login); // GitHub 用户名
🛡️ OAuth 与 JWT 的区别?
项目 | OAuth2 | JWT |
---|---|---|
作用 | 授权协议 | Token 格式规范 |
是否包含身份信息 | 不一定 | ✅ 可嵌入用户 ID |
推荐用途 | 第三方登录、资源授权 | API 鉴权、微服务认证 |
tip
你可以在 OAuth2 协议中使用 JWT 作为 access_token 的格式,但二者不是同一个东西。
🧠 常见问题与注意事项
是否可以将 access_token 存在前端?
✅ 可以,但建议存储在 HttpOnly Cookie
中,避免 XSS 泄露。
access_token 和 refresh_token 区别?
- access_token:用于访问接口,有时 效(如 2 小时)
- refresh_token:用于换新 token,有较长时效(如 7 天)