《身份认证机制深度解析》
第4章 基于令牌的认证

4、基于令牌的认证:Token 概念、Bearer Token、JWT 结构

📌 4.1 Token 核心概念

令牌(Token)是一种代表用户身份或授权信息的凭证,用于在无状态协议(如 HTTP)中传递身份信息。与传统的 Session-Cookie 机制不同,Token 认证无需在服务端存储会话状态,具有更好的扩展性和跨域支持。

🔑

无状态

服务端无需存储 Token,仅需验证签名即可确认身份

🌐

跨域友好

Token 可轻松在多个域名、移动端、第三方应用间共享

🛡️

安全性

结合签名与加密机制,防止篡改和伪造

👤 客户端 🖥️ 服务端 ① 登录凭证 ② 签发 Token 🎫 Token

📌 4.2 Bearer Token

Bearer Token 是一种最常用的 Token 类型,意为“持有者令牌”。只要持有该 Token,即可访问受保护的资源。通常通过 HTTP 请求头 Authorization: Bearer <token> 传递。

特性 说明
传递方式 Authorization: Bearer <token>
安全性要求 必须使用 HTTPS 传输,防止中间人窃取
有效期 通常较短(如 15 分钟),配合 Refresh Token 使用
作用域 可通过 scope 字段限制访问权限
📤 HTTP 请求示例 GET /api/user/profile HTTP/1.1 Host: api.example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

📌 4.3 JWT 结构详解

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间以 JSON 对象形式安全传输信息。JWT 由三部分组成:Header、Payload、Signature,以点号 . 分隔。

Header

{
  "alg": "HS256",
  "typ": "JWT"
}

算法 & 类型

.

Payload

{
  "sub": "1234567890",
  "name": "张三",
  "iat": 1516239022
}

声明数据

.

Signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

防篡改签名

Header alg: HS256 typ: JWT Base64URL 编码 . Payload sub: 123456 name: 张三 Base64URL 编码 . Signature HMAC-SHA256 (header + "." + payload) 密钥签名

📌 4.4 JWT 签发与验证流程

JWT 的签发与验证是认证系统的核心环节。签发时服务端使用密钥对 Header 和 Payload 进行签名;验证时服务端使用相同密钥重新计算签名并比对。

1

用户登录

客户端提交用户名和密码

→
2

服务端验证

校验凭证有效性

→
3

生成 JWT

组装 Header + Payload + 签名

→
4

返回 Token

客户端存储 Token

🔐 签发流程 用户凭证 验证身份 生成 JWT ✅ 🔍 验证流程 接收 JWT 解析 Header 验证签名 ✅ 💡 签名验证:服务端使用密钥对 Header + "." + Payload 重新计算签名,与 JWT 中的签名比对 💡 若签名不匹配或 Token 过期,则拒绝请求

📝 代码示例:JWT 签发与验证(Node.js)

const jwt = require('jsonwebtoken');
const secretKey = 'my_secret_key_123';

// 签发 JWT
function signToken(userId, username) {
  const payload = {
    sub: userId,
    name: username,
    iat: Math.floor(Date.now() / 1000),
    exp: Math.floor(Date.now() / 1000) + 3600  // 1小时过期
  };
  const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' });
  return token;
}

// 验证 JWT
function verifyToken(token) {
  try {
    const decoded = jwt.verify(token, secretKey, { algorithms: ['HS256'] });
    return { valid: true, data: decoded };
  } catch (err) {
    return { valid: false, error: err.message };
  }
}

// 使用示例
const myToken = signToken('1001', '张三');
console.log('签发 Token:', myToken);

const result = verifyToken(myToken);
console.log('验证结果:', result.valid ? '✅ 有效' : '❌ 无效');