jwt 这点小秘密,你们肯定都知道!

1. 在微服务背景和前后端分离开发风格下, jwt作为授权和信息交换的技术方案,得以广泛梭哈。

1> 授权

用户一旦通过登录认证, 会被下发一个token, 之后的每次请求都会带上这个token, 将能访问该token允许的资源/服务, 单点登录广泛采用了jwt, 因为它负载轻量且自然跨域使用。

2> 信息交换

jwt中含有轻量用户数据,有效使用JWT,可以降低服务器查询数据库的次数。利用非对称的公钥私钥,还可以做到可信的信息交换。

核心优势:

  • 无状态
  • 自包含
  • 天然跨域支持
  • 可扩展(自定义claims)

2. jwt(json web token)明面上是一个based64字符串, 那json从何而来?

jwt一般附加在请求头: Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU1MTkwNTEyLCJpYXQiOjE3NTQ4MzA1MTIsImp0aSI6ImRiY2M2ZjE4ODVlZjRmNTliODgxMzUyNzBiYWY1NTU2IiwidXNlcl9pZCI6MX0.JBQD87mcrRm6dG4tYdrxqV_fVDeuonsbPyJr2mgiFiM

静态结构有点类似基本身份认证basic authentication: Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

jwt token分为三块, 中间用.连接

  • header: 明文记录了token校验的算法(base64 算作明文)

    base64({"alg": "HS256","typ": "jWT"})

  • payload: 记录了下发身份信息的发牌人、发牌时间、过期时间、待传递身份信息

bash 复制代码
  base64({
  "token_type": "access",
  "exp": 1755190512,
  "iat": 1754830512,
  "jti": "dbcc6f1885ef4f59b88135270baf5556",
  "user_id": 1
})
  • sign: 通过算法(header中alg标记的算法)对header和payload做计算产生的签名字符串.

如果使用HS256对称加密算法:
sign= HMACSHA256(base64(header) + "." +base64(payload),secret)


jwt payload中的claims

iss Issuer 发牌人
sub Subject 主题
aud Audience claim的受众
exp Expiration Time 过期时间
iat Issued At 发牌时间
jti JWT ID jwt 的唯一id,用于防止重放攻击、或注销token

拒绝重放攻击

  • 攻击者截获了一个有效的 Token,试图重复使用。
  • 服务端可以通过检查jti是否已在"已使用列表"或"黑名单"中来拒绝重复请求。

注销token

  • 可以用jti作为 key 存储在 Redis 中,实现 Token 注销(logout)功能。
    例如:用户登出后,将 jti 加入黑名单,后续请求即使有有效签名也会被拒绝。

3.使用jwt token我们还应该知道什么?

  • JWT 默认是不加密,不能将敏感关键信息写入JWT。

  • JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

  • JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期应该设置得比较短,且使用HTTPS传输。对于一些比较重要的权限,使用时应该再次对用户进行认证。

4. jwt校验和jwt验证

客户端携带jwt token,服务端完整的校验流程

1> validation

  • 结构校验: 是否包含header,payload,sign 并以点号分割

  • 格式校验:每一部分是否都是base64 编码

  • 内容校验:检查payload 携带的claims是否正确: 过期时间exp、发牌时间iat, 令牌可用时间nbf

2> verification

  • 签名验证: 使用header 中约定的算法,服务器利用内置的secret key 或者 public key产生签名sign2,如果签名sign2 !=sign, 则令牌可能被篡改或并非来自可信来源。

密码学原理:

  • 如果header中约定使用对称加密, 那么发牌人和验证服务器共享密钥 secret key, 这个需要双方都妥善保管。
  • 如果header中约定使用非对称加密, 那么是由发牌人持私钥签名, 验证服务器持公钥public key验签。
特性 对称加密 非对称加密
加解密效率 ✅ 高 ❌ 较低
密钥管理 ❌ 难(需安全分发) ✅ 易(公钥可公开)
能否确认发送者身份? ❌ 不能(无不可否认性) ✅ 能(通过数字签名
相关推荐
JIngJaneIL7 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小信啊啊7 小时前
Go语言切片slice
开发语言·后端·golang
Victor3569 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易9 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧9 小时前
Range循环和切片
前端·后端·学习·golang
WizLC9 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor3569 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法9 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长10 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端
Python编程学习圈10 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端