返回主页 学习路径
OAuth 2.0 & JWT
委托授权 · 身份验证 · 无状态安全
OAuth 2.0 是由 IETF 于 2012 年发布的授权框架,允许第三方应用在用户授权下访问受保护资源,而无需获取用户密码。JWT(JSON Web Token)是基于 JSON 的开放标准(RFC 7519),用于在各方之间安全传输声明。OAuth 2.0 和 JWT 是现代 Web 应用、移动应用、微服务架构中认证和授权的核心标准,被 Google、Facebook、GitHub、微信等几乎所有大型平台采用。
认证授权标准 · 现代安全基石
📅 诞生时间2012年 · IETF (OAuth 2.0) / 2015年 · JWT (RFC 7519)
🧩 类型授权框架 · 安全令牌
📊 数据格式JSON / 令牌
⚡性能
8/10
📦生态
10/10
🧠易用
6/10
🚀扩展性
8/10

📑 本文目录

📌 第一部分:OAuth 2.0 & JWT 概览与定位

1.1 定义与全称

OAuth 2.0 是由 IETF 于 2012 年发布的授权框架,允许第三方应用在用户授权下访问受保护资源。JWT 是基于 JSON 的开放标准(RFC 7519),用于在各方之间安全传输声明。两者常结合使用,构成现代 Web 安全体系的核心。

1.2 核心定位

OAuth 2.0 的核心定位是 授权委托,JWT 的核心定位是 安全信息传递。它们提供了:

1.3 主要应用领域

1.4 知名案例


⚙️ 第二部分:核心概念

2.1 OAuth 2.0 核心角色

2.2 OAuth 2.0 授权流程

┌─────────┐      ┌──────────┐      ┌──────────┐      ┌─────────┐
│  用户   │      │  客户端  │      │ 授权服务器│      │ 资源服务器│
│(Resource│      │ (Client) │      │(Auth     │      │(Resource│
│ Owner)  │      │         │      │ Server)  │      │ Server) │
└────┬────┘      └────┬─────┘      └────┬─────┘      └────┬────┘
     │                │                │                │
     │ 1.请求授权     │                │                │
     │───────────────>│                │                │
     │                │                │                │
     │ 2.重定向到授权服务器             │                │
     │<───────────────│                │                │
     │                │                │                │
     │ 3.用户授权同意  │                │                │
     │───────────────>│                │                │
     │                │                │                │
     │ 4.返回授权码    │                │                │
     │<───────────────│                │                │
     │                │                │                │
     │                │ 5.用授权码换取令牌              │
     │                │───────────────>│                │
     │                │                │                │
     │                │ 6.返回 Access Token            │
     │                │<───────────────│                │
     │                │                │                │
     │                │ 7.用 Access Token 请求资源     │
     │                │───────────────────────────────>│
     │                │                │                │
     │                │ 8.返回受保护资源               │
     │                │<───────────────────────────────│
     │                │                │                │

2.3 OAuth 2.0 四种授权模式

2.4 JWT 结构

// JWT 格式:xxxxx.yyyyy.zzzzz

// Header(头部)
{
  "alg": "HS256",
  "typ": "JWT"
}

// Payload(载荷)
{
  "sub": "1234567890",
  "name": "Alice",
  "iat": 1516239022,
  "exp": 1516242622,
  "email": "alice@example.com",
  "role": "admin"
}

// Signature(签名)
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

// 完整 JWT 示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjIsImVtYWlsIjoiYWxpY2VAZXhhbXBsZS5jb20iLCJyb2xlIjoiYWRtaW4ifQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

2.5 JWT 常用声明


⚙️ 第三部分:代码实现

3.1 JWT 生成和验证(Node.js)

// 使用 jsonwebtoken 库
const jwt = require("jsonwebtoken");
const express = require("express");
const app = express();

const SECRET_KEY = "your-secret-key-here";

// 生成 JWT
function generateToken(user) {
    const payload = {
        id: user.id,
        email: user.email,
        role: user.role
    };
    return jwt.sign(payload, SECRET_KEY, { expiresIn: "7d" });
}

// 验证 JWT 中间件
function authenticateToken(req, res, next) {
    const authHeader = req.headers["authorization"];
    const token = authHeader && authHeader.split(" ")[1];

    if (!token) {
        return res.status(401).json({ error: "未提供认证令牌" });
    }

    jwt.verify(token, SECRET_KEY, (err, user) => {
        if (err) {
            return res.status(403).json({ error: "无效或过期的令牌" });
        }
        req.user = user;
        next();
    });
}

// 登录接口
app.post("/login", (req, res) => {
    const { email, password } = req.body;

    // 验证用户名密码(实际应从数据库查询)
    if (email === "alice@example.com" && password === "123456") {
        const user = { id: 1, email, role: "admin" };
        const token = generateToken(user);
        res.json({ token, user });
    } else {
        res.status(401).json({ error: "用户名或密码错误" });
    }
});

// 受保护接口
app.get("/api/users/me", authenticateToken, (req, res) => {
    res.json({ user: req.user });
});

// 刷新令牌
app.post("/api/auth/refresh", authenticateToken, (req, res) => {
    const user = req.user;
    const newToken = generateToken(user);
    res.json({ token: newToken });
});

3.2 JWT 生成和验证(PHP)

// 使用 firebase/php-jwt 库
require_once "vendor/autoload.php";

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secretKey = "your-secret-key-here";

// 生成 JWT
function generateToken($user) {
    global $secretKey;
    $payload = [
        "id" => $user["id"],
        "email" => $user["email"],
        "role" => $user["role"],
        "iat" => time(),
        "exp" => time() + (7 * 24 * 60 * 60) // 7 天
    ];
    return JWT::encode($payload, $secretKey, "HS256");
}

// 验证 JWT
function authenticateToken() {
    global $secretKey;
    $headers = getallheaders();
    $authHeader = $headers["Authorization"] ?? "";

    if (!preg_match("/Bearer\s+(.*)/", $authHeader, $matches)) {
        http_response_code(401);
        echo json_encode(["error" => "未提供认证令牌"]);
        exit;
    }

    $token = $matches[1];
    try {
        $decoded = JWT::decode($token, new Key($secretKey, "HS256"));
        return (array) $decoded;
    } catch (Exception $e) {
        http_response_code(403);
        echo json_encode(["error" => "无效或过期的令牌"]);
        exit;
    }
}

// 登录接口
if ($_SERVER["REQUEST_METHOD"] === "POST" && $_SERVER["REQUEST_URI"] === "/login") {
    $data = json_decode(file_get_contents("php://input"), true);
    if ($data["email"] === "alice@example.com" && $data["password"] === "123456") {
        $user = ["id" => 1, "email" => $data["email"], "role" => "admin"];
        $token = generateToken($user);
        echo json_encode(["token" => $token, "user" => $user]);
    } else {
        http_response_code(401);
        echo json_encode(["error" => "用户名或密码错误"]);
    }
    exit;
}

// 受保护接口
if ($_SERVER["REQUEST_METHOD"] === "GET" && $_SERVER["REQUEST_URI"] === "/api/users/me") {
    $user = authenticateToken();
    echo json_encode(["user" => $user]);
    exit;
}

3.3 JWT 生成和验证(Python)

# 使用 PyJWT 库
import jwt
import datetime
from flask import Flask, request, jsonify

app = Flask(__name__)
SECRET_KEY = "your-secret-key-here"

# 生成 JWT
def generate_token(user):
    payload = {
        "id": user["id"],
        "email": user["email"],
        "role": user["role"],
        "iat": datetime.datetime.utcnow(),
        "exp": datetime.datetime.utcnow() + datetime.timedelta(days=7)
    }
    return jwt.encode(payload, SECRET_KEY, algorithm="HS256")

# 验证 JWT 装饰器
def authenticate_token(f):
    def wrapper(*args, **kwargs):
        auth_header = request.headers.get("Authorization")
        if not auth_header or not auth_header.startswith("Bearer "):
            return jsonify({"error": "未提供认证令牌"}), 401

        token = auth_header.split(" ")[1]
        try:
            user = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
            request.user = user
        except jwt.ExpiredSignatureError:
            return jsonify({"error": "令牌已过期"}), 403
        except jwt.InvalidTokenError:
            return jsonify({"error": "无效的令牌"}), 403
        return f(*args, **kwargs)
    return wrapper

@app.route("/login", methods=["POST"])
def login():
    data = request.json
    if data["email"] == "alice@example.com" and data["password"] == "123456":
        user = {"id": 1, "email": data["email"], "role": "admin"}
        token = generate_token(user)
        return jsonify({"token": token, "user": user})
    return jsonify({"error": "用户名或密码错误"}), 401

@app.route("/api/users/me", methods=["GET"])
@authenticate_token
def get_current_user():
    return jsonify({"user": request.user})

if __name__ == "__main__":
    app.run(debug=True)

3.4 OAuth 2.0 授权码流程示例

// 前端重定向到授权服务器
const authUrl = "https://auth.example.com/authorize?" +
    "response_type=code" +
    "&client_id=your_client_id" +
    "&redirect_uri=https://yourapp.com/callback" +
    "&scope=openid%20profile%20email" +
    "&state=random_state_string";

window.location.href = authUrl;

// 回调处理(后端)
app.get("/callback", async (req, res) => {
    const { code, state } = req.query;

    // 验证 state(防 CSRF)
    if (state !== sessionState) {
        return res.status(400).json({ error: "无效的 state" });
    }

    // 用授权码换取 Access Token
    const tokenResponse = await fetch("https://auth.example.com/token", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: new URLSearchParams({
            grant_type: "authorization_code",
            code: code,
            redirect_uri: "https://yourapp.com/callback",
            client_id: "your_client_id",
            client_secret: "your_client_secret"
        })
    });

    const tokens = await tokenResponse.json();
    // tokens 包含 access_token, refresh_token, id_token

    // 使用 Access Token 获取用户信息
    const userInfo = await fetch("https://auth.example.com/userinfo", {
        headers: { "Authorization": `Bearer ${tokens.access_token}` }
    });

    const user = await userInfo.json();
    // 创建本地 session 或 JWT
    res.redirect("/dashboard");
});

🔒 第四部分:安全最佳实践

4.1 OAuth 2.0 安全建议

4.2 JWT 安全建议

4.3 常见攻击与防御


🧠 第五部分:学习建议

1
基础入门

OAuth 2.0 核心概念、四种授权模式、JWT 结构

2
核心进阶

JWT 生成与验证(多语言)、OAuth 2.0 授权码流程

3
高级特性

PKCE、刷新令牌、SSO、OpenID Connect

4
安全实践

安全配置、漏洞防护、生产环境最佳实践

推荐学习资源


🎯 总结升华

OAuth 2.0 & JWT 是现代 Web 安全的"通行证"。

OAuth 2.0 解决了 授权委托 的问题,JWT 解决了 安全信息传递 的问题。两者结合,构成了现代 API 安全、微服务认证、第三方登录的基础。

无论你是前端、后端还是 DevOps 工程师,OAuth 2.0 和 JWT 都是必须掌握的认证授权技术

"OAuth 2.0 & JWT 是互联网安全的"护照"。" 🛡️

🔖 相关标签
#认证 #授权 #JWT #OAuth 2.0 #SSO #安全 #API 安全
📄 本文档为 OAuth 2.0 & JWT 完整白皮书 · 最后更新于 2026年06月28日