彻底搞懂JWT令牌:原理与实战应用 为什么要使用JWT令牌随着前后端分离微服务分布式集群的普及使用传统的Session Cookie实现用户登录鉴权的弊端越来越明显例如导致服务端的存储压力变大对分布式架构不友好存在Cookie跨域限制等。一什么是JWT1.1JWT定义JWT 全称JSON Web Token是一种基于 JSON 格式的轻量级、无状态、可传输的开放标准令牌用于在客户端和服务端之间安全传输身份认证信息。简单来说服务端用户登录成功后生成一段加密的字符串令牌返回给客户端客户端后续所有请求携带该令牌服务端无需查询数据库即可直接校验用户身份和权限。1.2JWT特性1无状态服务端不存储JWT信息所有用户数据权限信息都加密存储在令牌本身彻底解决Session集群共享的问题2轻量简洁令牌体积小传输速度快2跨平台跨域名基于HTTP请求头传输不受Cookie跨域限制支持多段统一认证4可扩展可自定义携带用户信息以及过期信息等等二JWT核结构JWT令牌整体由三部分组成通过 . 分割格式为Header.Payload.Signature三部分均为Base64编码字符串。2.1Header头部作用是存储令牌的加密算法类型令牌类型由Base64编码可解码可篡改篡改后校验失败。2.2Payload载体作用是存储用户核心信息、令牌有效期等业务数据是JWT的核心载体Payload 只是 Base64 编码并非加密任何人都可以解码查看内容不能存储密码、密钥等敏感数据。2.3Signature 签名对 Header Payload 进行加密加盐密钥生成签名无法解密、无法篡改。一旦Header或Payload内容被修改重新计算的签名会和原签名不一致服务端直接判定令牌失效三JWT工作流程用户登录客户端提交账号密码到服务端身份校验服务端验证账号密码正确性校验通过后获取用户信息生成JWT令牌服务端根据用户信息、过期时间通过密钥加密生成JWT令牌返回令牌服务端将JWT返回给客户端客户端存储令牌前端将令牌存储在 LocalStorage / SessionStorage / Cookie 中携带令牌请求客户端后续所有接口请求在请求头Authorization中携带令牌服务端校验令牌服务端拦截器获取令牌验证签名是否合法、是否过期、信息是否篡改执行业务逻辑校验通过则放行请求执行业务逻辑四Session和JWT对比五JWT优缺点总结优点无状态高可用服务端不存储会话数据适配微服务分布式集群架构跨端跨域支持WebApp小程序彻底解决前后端分离跨域认证问题轻量化令牌体积小传输效率高请求开销小自带信息载荷可携带用户信息减少数据库查询次数缺点无法主动失效JW一旦签发过期前永久有效服务端无法主动注销令牌不可篡改但可解码载荷部分是明文编码不能存储敏感信息过期时间固定签发后无法修改有效期需要通过刷新令牌优化体验令牌过长自定义字段过多会导致令牌体积变大增加请求头传输压力六JWT安全问题解决方案6.1无法主动注销问题用户退出登录修改密码踢下时JWT未过期仍可使用存在安全风险解决方案引入redis黑名单机制在用户注销时将令牌存入Redis黑名单有效期与JWT过期时间一致请求时先校验黑名单。6.2JWT令牌过期强制用户重新登录用户体验差解决方案使用双令牌机制6.3数据篡改和泄露风险1使用非对称加密RS256代替对称加密HS256私钥签发公钥校验提升安全性2载荷部分禁止存敏感数据3使用HTTPS防止令牌被抓包窃取4设置合理过期时间避免令牌长期有效七常见问题7.1JWT的三段结构分别是什么以及各自的作用JWT由Header、Payload、Signature三部分组成。Header存储加密算法和令牌类型Payload存储用户信息和过期时间等业务数据Signature通过前两段加密生成用于防止令牌篡改保障安全性。7.2JWT是加密的吗JWT不是全程加密Header和Payload仅为Base64编码可直接解码查看只有签名部分加密。因此绝对不能存储密码、密钥等敏感数据。7.3JWT无状态有什么优缺点怎么解决主动失效问题无状态优点是服务端无需存储适配分布式性能高缺点是无法主动注销令牌解决方案是使用Redis维护JWT黑名单注销时存入令牌请求拦截校验黑名单实现主动失效前端删除不等于令牌过期过期时间由后端设置只要可以拿到旧的令牌还可以登录7.4JWT和Session的核心区别核心区别是存储方式呵呵状态Session服务端存储有状态JWT客户但你存储无状态。在项目中使用JWT主要是因为适配前后端分离微服务分布式架构解决Session跨域集群共享服务端压力大的问题。7.5双token机制的作用和原理单token存在问题过期时间太短用户频繁掉线体验差过期时间太长会加大被盗风险双token分为短期令牌Access和长期令牌Refresh。Access用于日常业务接口认证过期时间短降低被盗风险Refresh用于刷新令牌不参与业务实现用户无感续期解决JWT过期导致的频繁登录问题原理用户登录后服务器返回两个tokenRefresh和Access在Access令牌没过期之前每次请求后端使用Access当Access过期之后前端检测到Access过期会使用Refresh去请求后端后端校验Refresh并且校验通过之后会生成新的Access和新的Refresh。如果Refresh也失效了就需要用户再次登录了。双token即使短期Access被盗也会很快失效而单token要么过期时间久不安全要么过期时间短总掉线。