当前位置: 首页 > news >正文

一文读懂 JWT(JSON Web Token)

🔐 一文读懂 JWT(JSON Web Token)

一、什么是 JWT?

  • JWT(JSON Web Token)
    一种基于 JSON 的开放标准(RFC 7519),用于在各方之间安全地传递信息。
  • 特点
    1. 紧凑(Compact):可通过 URL、POST 参数或 HTTP 头传输
    2. 自包含(Self-contained):携带了用户的基本身份信息和声明(Claims)
    3. 可验证(Verifiable):签名保证数据未被篡改

📌 典型场景:用户登录后,服务器颁发一个 JWT,客户端每次请求都携带它,无需再查数据库做 Session 验证。


二、JWT 的三部分结构

一个典型的 JWT 长这样:

xxxxxxx.yyyyyyy.zzzzzzz
部分用途示例内容
Header(头部)指定算法和类型{"alg":"HS256","typ":"JWT"}
Payload(负载)存放声明(Claims),如用户 ID、过期时间等{"sub":"1234567890","name":"Alice","exp":1600000000}
Signature(签名)保证前两部分不被篡改HMACSHA256(Base64Url(Header) + "." + Base64Url(Payload), Secret)

注意:Header 和 Payload 都要做 Base64Url 编码!

JWT = Base64Url(Header) + "." + Base64Url(Payload) + "." + Base64Url(Signature)

三、JWT Secret(密钥)介绍 🔑

  1. 作用
    • 对称签名(HS256/HS384/HS512)中,Secret 用来签发验证 Token。
  2. 形式 & 长度
    • 高强度随机字节,建议 ≥256 bits(32 bytes)
    • 常见编码:
      • URL-Safe Base64
        9d6bXFMmZ3RV8Ytp9rz8QpKBuGV9zZ4T5vHSuJEjw8M
        
      • Hex
        e75ab5c53266774557c62da7dacfc429281b8695f736784f9bc74ae24923c3c30
        
  3. 如何生成?
    • Go 代码示例:
      import ("crypto/rand""encoding/base64""log"
      )func generateSecret() string {b := make([]byte, 32)if _, err := rand.Read(b); err != nil {log.Fatalf("生成 Secret 失败:%v", err)}// RawURLEncoding 去掉末尾 = 号,更 URL-Safereturn base64.RawURLEncoding.EncodeToString(b)
      }
      
  4. 泄露后果
    1. 攻击者可伪造任意合法 JWT,冒充用户或管理员
    2. 权限绕过、数据篡改、系统信任链崩溃
    3. 等同「根密钥」被盗,所有鉴权瞬间失效
  5. 防护 & 补救
    • 安全存储:✨使用 Vault、AWS KMS、GCP Secret Manager 等
    • 定期轮换(Key Rotation):支持「新」+「旧」秘钥平滑过渡
    • 缩短生命周期:结合 exp,让 Token & Secret 都有“有效期”
    • 多重验证:对支付、重置密码等关键操作再做一次二次校验
    • 监控告警:异常签名、同账户多地登录及时告警并强制登出

四、签名算法(alg)

算法名称描述
HS256HMAC + SHA-256,对称加密(Shared Secret)
HS384HMAC + SHA-384
HS512HMAC + SHA-512
RS256RSA + SHA-256,非对称加密(公钥/私钥对)
ES256ECDSA + SHA-256,椭圆曲线数字签名算法

小项目常用 HS256;高安全需求可选 RS256(私钥签发、公钥验签)。


五、JWT 的工作流程

  1. 用户登录(提供用户名/密码)
  2. 服务器验证成功后,签发 JWT
  3. 客户端保存(LocalStorage / Cookie)
  4. 后续请求携带 JWT
    • 推荐:请求头 Authorization: Bearer <token>
  5. 服务器 验证签名 & 检查声明(如是否过期、是否有权限)
  6. 验证通过,返回数据;否则 401 Unauthorized
UserClientServer输入用户名 & 密码POST /login返回 JWT(Header.Payload.Signature)GET /profile + Authorization: Bearer <JWT>返回 200 OK + 用户信息UserClientServer

六、签名 & 验证(HS256 示例)

1. 签名生成

H = Base64Url(Header)
P = Base64Url(Payload)
Secret = 服务器持有的密钥

LaTeX 公式版:

Signature=HMACSHA256(H+"."+P, Secret) \mathrm{Signature} = \mathrm{HMACSHA256}\bigl(H + "." + P,\ \mathrm{Secret}\bigr) Signature=HMACSHA256(H+"."+P, Secret)

2. 验证流程

  1. 拆分 Header.Payload.Signature
  2. 重新计算 HMACSHA256(H+"."+P, Secret)
  3. 对比结果:
    • 相同:✅ 数据未被篡改
    • 不同:❌ 拒绝访问

七、优缺点一览

优点缺点
1. 无状态(Stateless),可水平扩展 🌐1. 无法即时「撤销」已签发的 Token
2. 携带信息自包含,无需多次查询数据库 📦2. Token 泄露风险大,需妥善存储
3. 支持跨域认证(适合微服务、移动端)📱🌍3. Payload 明文可读,敏感信息请勿存放

八、实战示例(Go 语言版)

下面用 Go + 标准库 + github.com/golang-jwt/jwt/v4 库演示:

package mainimport ("crypto/rand""encoding/base64""fmt""log""net/http""strings""time""github.com/golang-jwt/jwt/v4"
)// 1. 生成 Secret
func generateSecret() string {b := make([]byte, 32)if _, err := rand.Read(b); err != nil {log.Fatalf("生成 Secret 失败:%v", err)}return base64.RawURLEncoding.EncodeToString(b)
}// 全局 Secret(示例中硬编码,生产环境请用安全存储)
var SECRET = generateSecret()// 2. 签发 JWT
func createToken(username string) (string, error) {claims := jwt.MapClaims{"sub": username,"name": "Alice","iat": time.Now().Unix(),"exp": time.Now().Add(time.Hour).Unix(),}token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)return token.SignedString([]byte(SECRET))
}// 3. 验证 JWT
func verifyToken(tokenStr string) (*jwt.Token, error) {return jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])}return []byte(SECRET), nil})
}func main() {http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {// 仅示例:实际应解析 JSON & 验证数据库username, password := r.URL.Query().Get("user"), r.URL.Query().Get("pass")if username == "alice" && password == "123" {token, err := createToken(username)if err != nil {http.Error(w, "Token 签发失败", 500)return}fmt.Fprintf(w, `{"token":"%s"}`, token)return}http.Error(w, "用户名或密码错误", 401)})http.HandleFunc("/profile", func(w http.ResponseWriter, r *http.Request) {auth := r.Header.Get("Authorization")parts := strings.SplitN(auth, " ", 2)if len(parts) != 2 || parts[0] != "Bearer" {http.Error(w, "缺少或无效的 Authorization 头", 401)return}token, err := verifyToken(parts[1])if err != nil || !token.Valid {http.Error(w, "Token 无效或已过期", 401)return}claims := token.Claims.(jwt.MapClaims)fmt.Fprintf(w, `{"user":"%s","name":"%s"}`, claims["sub"], claims["name"])})log.Printf("🔑 Secret(演示用): %s\n", SECRET)log.Println("🚀 Server 启动: http://localhost:8080")log.Fatal(http.ListenAndServe(":8080", nil))
}

启动后:

  1. 登录:
    GET http://localhost:8080/login?user=alice&pass=123
  2. 拿到 {"token":"..."}
  3. 请求受保护路由:
    GET /profile HTTP/1.1
    Host: localhost:8080
    Authorization: Bearer <token>
    

九、总结 & 小贴士

  1. Secret 存储
    • 生产环境切勿硬编码,使用专业密钥管理服务(Vault, AWS KMS…)
  2. Token 生命周期
    • 设置合理 exp,并对关键操作做二次校验
  3. 安全细节
    • Payload 明文可读,切勿存敏感数据
    • 定期轮换 Secret,缩小泄露风险窗口
    • 始终启用 HTTPS,防止中间人攻击

🎉 至此,你已经掌握了 JWT 的核心原理、结构、Secret 要点、使用流程及 Go 实战示例。快去项目中试一试吧!

http://www.lryc.cn/news/601246.html

相关文章:

  • Spring Boot2错误处理
  • Android网络框架封装 ---> Retrofit + OkHttp + 协程 + LiveData + 断点续传 + 多线程下载 + 进度框交互
  • 【AI阅读】20250717阅读输入
  • Linux YUM 安装:高效管理软件包的利器
  • 白杨SEO:搜索引擎优化中的allintitle是什么指令?有哪些用处?
  • 8. 状态模式
  • 【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程
  • ACL原理和配置
  • 【element-ui】HTML引入本地文件出现font找不到/fonts/element-icons.woff
  • 【lucene】MMapDirectory 在FSDirectory基础上干了啥?
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情分析实现
  • AI驱动的金融推理:Fin-R1模型如何重塑行业决策逻辑
  • listen() 函数详解
  • GPGPU基本概念
  • 深入解析 Vue 3 中 v-model 与表单元素的绑定机制
  • 北京-4年功能测试2年空窗-报培训班学测开-第六十一天-模拟面试第一次
  • 五自由度磁悬浮轴承转子不平衡振动破壁战:全息前馈控制实战密码
  • 结构化文本文档的内容抽取与版本重构策略
  • 程序代码篇---python获取http界面上按钮或者数据输入
  • LeetCode 611.有效三角形的个数
  • 机器学习项目一基于KNN算法的手写数字识别
  • 设计模式(十二)结构型:享元模式详解
  • AI Coding IDE 介绍:Cursor 的入门指南
  • 设计模式(八)结构型:桥接模式详解
  • 以太坊ETF流入量超越比特币 XBIT分析买币市场动态与最新价格
  • 分类预测 | MATLAB基于四种先进的优化策略改进蜣螂优化算法(IDBO)的SVM多分类预测
  • 机器学习—线性回归
  • 数学基础薄弱者的大数据技术学习路径指南
  • Java Ai (day01)
  • Oracle EBS 库存期间关闭状态“已关闭未汇总”处理