JWT令牌
一、什么是 JWT
JWT(JSON Web Token):是一种轻量级、自包含、无状态的 JSON 格式令牌,是目前前后端分离、分布式系统最主流的登录鉴权方案。
核心作用:替代传统 Session,完成用户身份认证、接口鉴权、简单信息传递。
二、为什么需要 JWT(诞生背景)
-
HTTP 协议无状态,服务器无法自动识别用户身份;
-
传统 Session 保存在服务端,分布式、多服务很难共享,扩展性差;
-
Cookie 依赖浏览器、跨域限制大、无法适配 APP、小程序多端场景;
-
JWT 无状态、客户端存储、天然适配分布式微服务架构。
三、JWT 结构(三段式)
整体格式:Header.Payload.Signature,三部分均为 Base64Url 编码(可解码、不加密)
1. Header 头部
存储令牌基础信息,体积很小
-
typ:令牌类型,固定为 JWT
-
alg:签名算法,主流 HS256对称加密、RS256非对称加密
2. Payload 载荷 ⚠️重点
存放业务数据与令牌时效信息,分为标准声明和自定义声明。
标准声明:
-
exp:过期时间(核心字段)
-
iat:签发时间
-
sub:用户唯一标识
-
iss:签发方
自定义声明:userId、用户名、角色、权限标识等业务字段
致命注意:Payload 只编码、不加密,任何人都可解码查看,严禁存储密码、手机号等敏感数据。
3. Signature 签名(防篡改核心)
生成规则:将编码后的 Header + Payload,结合服务端私有密钥通过指定算法加密生成。
核心作用:
-
校验令牌是否被篡改
-
防止伪造非法 Token
-
密钥仅服务端持有,安全性可控
四、JWT 完整登录流程
-
用户提交账号密码,后端校验身份合法性;
-
校验通过后,后端携带用户信息、过期时间、私有密钥生成 JWT;
-
将 JWT 返回前端,前端自主存储;
-
前端所有接口请求,在 Request 请求头携带 Token;
-
后端统一拦截器拦截请求,校验 Token 签名合法性、是否过期;
-
校验通过,解析用户信息完成鉴权,放行接口;校验失败,拦截请求返回未登录。
五、JWT 优缺点
✅ 优点
-
无状态:服务端无需存储会话,不占用服务器内存、Redis资源
-
自包含:令牌自带用户、权限信息,无需频繁查询缓存/数据库
-
跨端跨域:不依赖Cookie,完美适配Web、APP、小程序
-
分布式友好:微服务多系统无需共享会话,任意服务均可独立鉴权
❌ 缺点
-
无法主动作废:令牌签发后,到期前永久有效,无法单方面强制失效
-
续签体验差:单一Token设置短时有效期用户频繁掉线,长时有效期被盗风险高
-
存在重放攻击风险:令牌一旦被盗,攻击者可冒用身份请求接口
-
载荷不安全:仅Base64编码,可直接解码,不能存储敏感数据
六、生产落地解决方案 🔴
1. 双Token机制⭐最常用
解决:续签麻烦、安全性低的问题
-
AccessToken(访问令牌):短期有效(30min-1h),专门用于接口鉴权,降低被盗风险
-
RefreshToken(刷新令牌):长期有效(7-30天),不参与业务鉴权,仅用于刷新AccessToken
无感续签流程:AccessToken过期 → 前端携带RefreshToken请求刷新接口 → 后端校验合法,下发全新双Token → 用户无需重新登录。
2. 令牌注销、强制下线方案
-
Redis黑名单:用户注销/被踢下线时,将未过期Token存入黑名单,鉴权优先校验黑名单
-
版本号机制:用户表新增token版本号,JWT携带版本号,改密码、强制下线时版本号自增,旧令牌直接失效
七、前端存储选型与场景匹配
1. LocalStorage 存储
方案:请求头手动携带Token
场景:对外C端、前后端分离项目、多端适配、无需跨子域单点登录
缺点:易遭受XSS攻击
2. Cookie 存储(根域SSO)
方案:JWT存入Cookie,设置 Domain=.主域名、HttpOnly、Secure
场景:企业内部多子系统、同根域名轻量级单点登录
优点:浏览器自动携带、防XSS、实现跨子域免登
八、面试辨析:JWT / Session / OAuth2.0
-
Session:服务端存储会话,依赖Cookie,适合单体内部系统,分布式扩展性差
-
JWT:自研令牌鉴权,适合自家项目登录、双Token鉴权、轻量级跨子域SSO
-
OAuth2.0:标准化授权协议,只用于第三方登录、跨企业系统授权,普通项目属于过度设计
九、总结
JWT是轻量级无状态的JSON令牌,由头部、载荷、签名三部分组成,依靠签名机制防止令牌篡改。它解决了传统Session在分布式系统难以共享的问题,跨端适配性强,但存在无法主动作废、续签困难、载荷不安全等问题。生产环境通常采用双Token机制实现用户无感续签,搭配Redis黑名单或版本号机制实现令牌强制失效。对外前后端分离项目一般将Token存在本地、通过请求头鉴权;内部同根域多子系统可将JWT存入根域Cookie,实现轻量级单点登录。