一、JWT 是什么?
JWT(JSON Web Token) 是一种无状态的身份认证令牌标准(RFC 7519)。
一句话版:
JWT = 把用户身份信息签名后,塞进一个字符串里,让服务端不用存 Session 也能校验身份
常用于:
- 登录鉴权(Authentication)
- 接口授权(Authorization)
- 微服务之间的身份传递
可以参考官网
JWT官网:https://www.jwt.io/
如下网站提供在线验证JWT有效性
JWT在线验证:https://www.bejson.com/jwt/
二、JWT 的结构(重点)
JWT 看起来像这样:
xxxxx.yyyyy.zzzzz
由 三部分组成 (用 . 分隔):
1️⃣ Header(头部)
描述 token 类型和签名算法:
json
{
"alg": "HS256",
"typ": "JWT"
}
alg:签名算法(HS256 / RS256)typ:类型,通常是 JWT
Base64Url 编码后就是第一段。
2️⃣ Payload(载荷 / Claims)
真正存放业务数据的地方:
json
{
"sub": "user123",
"iss": "kms-auth",
"aud": "kms-api",
"exp": 1769752803,
"iat": 1769750000,
"scope": "read write"
}
常见标准 Claim(强烈建议使用)
| Claim | 含义 |
|---|---|
sub |
subject,用户唯一标识 |
iss |
issuer,签发方 |
aud |
audience,接收方 |
exp |
过期时间(秒级时间戳) |
iat |
签发时间 |
jti |
token 唯一 ID |
⚠️ Payload 是可解码的,不是加密的!
不要放密码、秘钥、隐私数据
3️⃣ Signature(签名)
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
作用:
- 防篡改
- 校验 token 是否由可信方签发
三、JWT 的工作流程
以登录为例:
用户 → 登录
→ 服务端校验账号密码
→ 生成 JWT
→ 返回给客户端
之后每次请求:
客户端 → Authorization: Bearer <JWT>
服务端 → 验签 + 校验 exp/iss/aud
→ 放行 or 拒绝
🚀 服务端不存 Session,真正的无状态
✅总体流程如下图:
是
否
合法
非法
用户登录
认证服务校验账号密码
生成 JWT Access Token
返回 Token 给客户端
客户端请求业务接口
Authorization: Bearer JWT
业务服务 / 网关
Token 是否有效?
放行并返回业务数据
返回 401 Token Expired
客户端携带 refresh_token
认证服务校验 refresh_token
签发新的 Access Token
要求重新登录
👉注意:
一般客户端可以解析token的过期时间,快过期时则重新使用refresh_token 换取新的access_token
四、JWT 的优点 & 缺点
✅ 优点
- 无状态:适合分布式 / 微服务
- 跨语言:前后端、服务间通用
- 性能好:无需查 Session
- 标准化:生态成熟
❌ 缺点(很多人踩坑)
1️⃣ 无法主动失效
- token 没过期之前,服务端默认都认
- 解决方案:
- 短 access_token + refresh_token
- 黑名单(Redis 存 jti)
2️⃣ Payload 明文
- 只是 Base64,不是加密
- 敏感信息放数据库 / Redis
3️⃣ Token 变大
- header + payload + 签名
- 不适合塞太多 claim
五、常见签名算法选择
🔐 HS256(对称)
- 一个
secret - 签发和校验用同一个秘钥
- 适合单体 / 简单系统
🔐 RS256(非对称,推荐)
- 私钥签发
- 公钥验签
- 适合微服务、第三方接入
六、JWT vs Session(面试高频)
| 对比项 | JWT | Session |
|---|---|---|
| 状态 | 无状态 | 有状态 |
| 存储 | 客户端 | 服务端 |
| 分布式 | 天然支持 | 需要 Session 共享 |
| 主动失效 | 困难 | 简单 |
| 安全 | 依赖签名 | 依赖服务端 |
👉 高并发 / 微服务:JWT
👉 后台管理 / 强控制:Session
七、最佳实践(血泪总结)
✔ access_token 10~30 分钟
✔ refresh_token 单独接口换
✔ 必校验:exp / iss / aud
✔ jti + Redis 支持踢人
✔ HTTPS(JWT + HTTP = 裸奔)