jwt学习

一、JWT 是什么?(核心定义)

  • 全称:JSON Web Token
  • 本质 :一种轻量级、自包含的令牌(Token),以 JSON 格式存储用户身份 / 权限等信息,可在客户端和服务端之间安全传输。
  • 核心特点
    • 自包含:Token 本身包含所有认证信息,服务端无需查库 / 缓存即可验证身份(对比 Session:需服务端存储会话信息);
    • 跨域 / 跨服务:基于字符串传输,适配前后端分离、微服务跨服务认证场景;
    • 可签名:支持对称加密(HMAC)或非对称加密(RSA),防止 Token 被篡改。

二、JWT 的核心结构(三段式,必背)

JWT 由 Header(头部)、Payload(载荷)、Signature(签名) 三部分组成,各部分用 . 分隔,最终格式如:

plaintext

复制代码
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInVzZXJuYW1lIjoiemhhbmdzYW4iLCJleHAiOjE3MTk4MTU4MDJ9.5Z8n9jG0Q7t2X8kL7s9a8d7f6g5h4j3k2l1m0n9b8v7c6x5s4d3f2g1h0j9k8l7m6n5b4v3c2x1s0a9s8d7f6g5h4j3k2l1

1. Header(头部)

  • 作用:描述 JWT 的元数据(加密算法、令牌类型);

  • 格式 :JSON 字符串,通常包含两个字段:

    • alg:使用的签名算法(如 HS256(HMAC-SHA256)、RS256(RSA-SHA256));
    • typ:令牌类型,固定为 JWT
  • 示例

    json

    复制代码
    {
      "alg": "HS256",
      "typ": "JWT"
    }
  • 处理:Base64Url 编码(不是加密,可反向解码),成为 JWT 第一部分。

2. Payload(载荷)

  • 作用:存储实际需要传递的信息(用户 ID、用户名、过期时间等);

  • 分类

    • 「注册声明」(推荐使用,预定义字段): 表格

      字段名 含义 示例
      iss 签发者(Token 发行方) https://xxx.com
      sub 主题(面向的用户) 1001(用户 ID)
      exp 过期时间(时间戳) 1719815802(必加)
      nbf 生效时间 1719810000
      iat 签发时间 1719810802
      jti JWT 唯一标识 f89s7d6g5h4j3k2l1
    • 「公共声明」:自定义字段(如 usernamerole),但避免存敏感信息;

    • 「私有声明」:前后端协商的自定义字段(如 userId);

  • 示例

    json

    复制代码
    {
      "userId": 1,
      "username": "zhangsan",
      "exp": 1719815802
    }
  • 处理:Base64Url 编码,成为 JWT 第二部分(⚠️ 可解码,绝对不能存密码、token 等敏感信息)。

3. Signature(签名)

  • 作用:验证 Token 是否被篡改,保证数据完整性;

  • 生成逻辑

    1. 将编码后的 Header + . + 编码后的 Payload 拼接成字符串;
    2. 使用 Header 中指定的算法,结合「密钥」对该字符串进行加密;
  • 示例(HS256 算法)

    plaintext

    复制代码
    HMACSHA256(
      base64UrlEncode(Header) + "." + base64UrlEncode(Payload),
      "my-secret-key" // 服务端唯一密钥,绝对不能泄露
    )
  • 处理:加密结果作为 JWT 第三部分(无法反向解密,仅用于验证)。

三、JWT 的核心工作流程(前后端分离场景)

以「用户登录获取 Token,后续请求携带 Token 认证」为例:

预览

查看代码

服务端客户端服务端客户端提交用户名+密码(登录请求)验证用户名密码是否正确验证通过,生成 JWT(包含用户ID、过期时间)返回 JWT(如:响应体中 `token: "eyJhbGciOiJIUzI1Ni..."`)存储 JWT(LocalStorage/SessionStorage/Cookie)发起后续请求(如:获取用户信息),请求头携带 JWT(Authorization: Bearer {token})验证 JWT 签名+过期时间,解析出用户ID返回请求结果(无需再次验证密码)

复制代码
sequenceDiagram
    participant 客户端
    participant 服务端
    客户端->>服务端: 提交用户名+密码(登录请求)
    服务端->>服务端: 验证用户名密码是否正确
    服务端->>服务端: 验证通过,生成 JWT(包含用户ID、过期时间)
    服务端->>客户端: 返回 JWT(如:响应体中 `token: "eyJhbGciOiJIUzI1Ni..."`)
    客户端->>客户端: 存储 JWT(LocalStorage/SessionStorage/Cookie)
    客户端->>服务端: 发起后续请求(如:获取用户信息),请求头携带 JWT(Authorization: Bearer {token})
    服务端->>服务端: 验证 JWT 签名+过期时间,解析出用户ID
    服务端->>客户端: 返回请求结果(无需再次验证密码)

服务端客户端服务端客户端提交用户名+密码(登录请求)验证用户名密码是否正确验证通过,生成 JWT(包含用户ID、过期时间)返回 JWT(如:响应体中 `token: "eyJhbGciOiJIUzI1Ni..."`)存储 JWT(LocalStorage/SessionStorage/Cookie)发起后续请求(如:获取用户信息),请求头携带 JWT(Authorization: Bearer {token})验证 JWT 签名+过期时间,解析出用户ID返回请求结果(无需再次验证密码)

关键步骤说明:

  1. Token 生成:登录成功后,服务端根据用户信息 + 密钥生成 JWT,返回给客户端;
  2. Token 存储:客户端将 JWT 存在 LocalStorage(跨域友好)或 Cookie(更安全);
  3. Token 携带 :后续请求通过 Authorization 请求头携带(规范格式:Bearer + 空格 + JWT);
  4. Token 验证 :服务端收到 Token 后:
    • 拆分 Header/Payload/Signature;
    • 用相同密钥 + 算法验证签名(防止篡改);
    • 检查 exp 字段(防止 Token 过期);
    • 验证通过则解析 Payload 中的用户信息,处理请求。

四、JWT 的核心使用场景

表格

场景 优势
前后端分离认证 无需服务端存储 Session,跨域友好
微服务跨服务授权 服务间传递身份信息,无需重复认证
一次性验证(如邮件激活) 可设置短过期时间,结合 jti 防止重复使用
移动端 API 认证 轻量级字符串,适配移动端网络传输

五、JWT 的优缺点(面试高频)

优点

  1. 无状态:服务端无需存储 Token,减轻服务器压力(对比 Session:需存储会话,分布式场景需 Redis 共享);
  2. 跨域 / 跨服务:Token 是字符串,可在任意平台传递,适配前后端分离、微服务;
  3. 自包含:Payload 可存储基础用户信息,减少服务端查库次数;
  4. 易扩展:支持多种加密算法,可按需选择对称 / 非对称加密。

缺点

  1. 无法主动吊销:Token 生成后,除非过期,否则无法主动作废(如用户退出登录,服务端仍需验证 Token,解决方案:结合 Redis 维护黑名单);
  2. Payload 可解码:Base64Url 编码不是加密,Payload 中的信息可被解码,绝对不能存敏感信息(如密码、银行卡号);
  3. Token 可能过长:如果 Payload 存储过多信息,Token 字符串会变长,增加网络传输开销;
  4. 过期时间固定:无法动态修改 Token 过期时间(需重新生成 Token)。

六、JWT 实战关键注意事项(避坑指南)

1. 安全相关(重中之重)

  • 绝不存敏感信息:Payload 仅存用户 ID、用户名、角色等非敏感信息,密码、token 等绝对不能存;
  • 密钥绝对保密:对称加密的密钥(如 HS256 的密钥)需妥善保管,泄露则攻击者可伪造 Token;
  • 使用 HTTPS 传输:防止 Token 在网络传输中被劫持;
  • 设置合理过期时间:短期过期(如 2 小时),结合「刷新令牌(Refresh Token)」实现无感续期;
  • 避免用 Base64 编码混淆敏感信息:Base64Url 可轻松解码,不要误以为是加密。

2. 续期方案(解决 Token 过期问题)

  • 双 Token 机制
    • Access Token:短期有效(2 小时),用于接口认证;
    • Refresh Token:长期有效(7 天),用于 Access Token 过期后,获取新的 Access Token;
    • 优势:无需用户重新登录,实现无感续期。

3. 吊销 Token(解决 "无法主动作废" 问题)

  • 结合 Redis 维护「Token 黑名单」:
    • 用户退出登录 / 账号异常时,将 Token 存入 Redis(设置与 Token 相同的过期时间);
    • 服务端验证 Token 时,先检查 Redis 黑名单,存在则拒绝请求。

4. 技术选型(Java 生态)

  • 推荐依赖:jjwt(Java JWT 工具包,简单易用);

  • 核心代码示例(生成 / 验证 Token): java

    运行

    复制代码
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.security.Keys;
    import javax.crypto.SecretKey;
    import java.util.Date;
    
    public class JwtUtil {
        // 密钥(建议至少 256 位,避免弱密钥)
        private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor("my-secret-key-12345678901234567890".getBytes());
        // 过期时间:2 小时
        private static final long EXPIRATION = 2 * 60 * 60 * 1000;
    
        // 生成 Token
        public static String generateToken(Long userId, String username) {
            return Jwts.builder()
                    .claim("userId", userId) // 自定义字段
                    .claim("username", username)
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 过期时间
                    .signWith(SECRET_KEY) // 签名
                    .compact();
        }
    
        // 验证 Token 并解析用户ID
        public static Long getUserIdFromToken(String token) {
            return Jwts.parserBuilder()
                    .setSigningKey(SECRET_KEY)
                    .build()
                    .parseClaimsJws(token) // 验证签名,失败则抛异常
                    .getBody()
                    .get("userId", Long.class);
        }
    }

七、JWT vs Session(面试对比)

表格

特性 JWT Session
存储位置 客户端(LocalStorage/Cookie) 服务端(内存 / Redis)
状态 无状态 有状态
跨域 友好(字符串传输) 不友好(Cookie 跨域限制)
分布式部署 无需额外配置 需 Redis 共享 Session
主动吊销 困难(需结合黑名单) 简单(直接删除服务端 Session)
数据大小 可自定义(不宜过大) 服务端存储,无传输大小限制

总结

  1. 核心结构:JWT = Header(Base64Url) + Payload(Base64Url) + Signature(加密),三段式字符串;
  2. 核心流程:登录生成 Token → 客户端存储 → 请求携带 Token → 服务端验证签名 + 过期时间;
  3. 核心注意:不存敏感信息、密钥保密、设置短过期时间、结合 Redis 解决吊销问题;
  4. 核心优势:无状态、跨域友好,适配前后端分离 / 微服务架构;
  5. 核心缺点:无法主动吊销、Payload 可解码,需结合额外方案弥补。
相关推荐
952362 小时前
MySQL - 集群架构与实践
数据库·学习·mysql·架构
凸头2 小时前
美团Leaf发号器
java
V搜xhliang02462 小时前
手术机器人导航软件
大数据·人工智能·机器学习·自然语言处理·机器人
SmartBrain2 小时前
基于 Spring AI 构建多智能体协作系统(高级版)
java·人工智能·spring
艾莉丝努力练剑2 小时前
文件描述符fd:跨进程共享机制
java·linux·运维·服务器·开发语言·c++
工藤新一¹2 小时前
《操作系统》第一章(1)
java·服务器·前端
Han.miracle2 小时前
Lombok 构造相关核心注解全解析
java·linux·算法
Java面试题总结2 小时前
2026最新Java八股文(完整版)
java·开发语言·jvm·数据库·java面试·java八股文
6+h2 小时前
【java】System类详解
java·开发语言·python