JWT 鉴权机制详解

2026-06-22 · 6 阅读 · 327字
API设计Go安全

JWT 鉴权机制详解

什么是 JWT

JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以 JSON 对象的形式安全传输信息。

JWT 结构

JWT 由三部分组成,以点号分隔:

header.payload.signature

Header(头部)

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

Payload(负载)

包含声明(claims),分为三类:

  • 注册声明iss(签发者)、sub(主题)、exp(过期时间)、iat(签发时间)
  • 公共声明:自定义字段,建议在 IANA 注册或使用命名空间避免冲突
  • 私有声明:双方协商的自定义字段
{
    "sub": "1234567890",
    "name": "张三",
    "iat": 1516239022,
    "exp": 1516242622,
    "role": "admin"
}

Signature(签名)

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

鉴权流程

1. 用户登录 → 服务器验证凭据 → 签发 JWT → 返回给客户端

2. 客户端存储 JWT(localStorage / Cookie)→ 每次请求在 Authorization 头携带

3. 服务器接收请求 → 验证 JWT 签名 → 解析 payload → 执行鉴权逻辑

使用示例(Go)

生成 JWT

import "github.com/golang-jwt/jwt/v5"

type Claims struct {
    UserID string `json:"user_id"`
    Role   string `json:"role"`
    jwt.RegisteredClaims
}

func GenerateToken(userID, role string) (string, error) {
    claims := &Claims{
        UserID: userID,
        Role:   role,
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
            IssuedAt:  jwt.NewNumericDate(time.Now()),
            Issuer:    "my-app",
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return token.SignedString([]byte("your-secret-key"))
}

验证 JWT

func ValidateToken(tokenString string) (*Claims, error) {
    token, err := jwt.ParseWithClaims(tokenString, &Claims{},
        func(token *jwt.Token) (interface{}, error) {
            if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
                return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
            }
            return []byte("your-secret-key"), nil
        })

    if err != nil {
        return nil, err
    }

    claims, ok := token.Claims.(*Claims)
    if !ok || !token.Valid {
        return nil, fmt.Errorf("invalid token")
    }

    return claims, nil
}

安全注意事项

签名算法

  • 使用强签名算法如 HS256 或 RS256
  • 服务端验证时必须校验 alg 头,防止算法混淆攻击

密钥管理

  • HS256:密钥足够复杂,定期轮转
  • RS256:私钥妥善保管,公钥分发到各服务

Token 存储

  • 前端:优先使用 httpOnly Cookie(防 XSS),而非 localStorage
  • 后端:永远不要存储明文的 JWT

Token 失效

JWT 签发后无法服务端主动撤销。解决方案:

  1. 短过期时间 + 刷新 Token:access token 15 分钟,refresh token 7 天
  2. 黑名单:使用 Redis 维护失效 Token 集合
  3. 版本号:用户密码变更时递增版本号,验证时对比

与 Session 的对比

特性 JWT Session
存储方式 客户端 服务端内存/Redis
扩展性 天然无状态,易水平扩展 需要共享存储
主动失效 复杂(需黑名单) 直接删除 Session
数据量 Token 较大 仅 Session ID
安全性 注意 XSS/CSRF 相对成熟