怎么是用JWT

什么是JWT

jwt全称Json-Wen-Token------基于json的web令牌,用来当做登录凭证、代替传统 Session 的一串加密字符串。

  • Session:小区物业给你一张纸质门禁卡,物业后台登记你的信息;卡丢了物业可以直接作废。
  • JWT:一张自带全部个人信息、并且盖了物业钢印的门禁卡 卡片本身就写着你的用户 ID、名字;钢印用来防止你私自篡改卡片信息。 后端不需要往数据库 / Redis 存一份会话,拿到卡片就能认出你是谁。

JWT的结构

  1. header (头部):加密算法,例如 HS512
  2. payload (载荷):存放用户数据:userId、username、过期时间
  3. signature (签名,钢印) 使用你后端自定义密钥加密签名; 一旦载荷内容被人篡改,签名就校验失败,后端直接判定令牌非法。

JWT使用流程

  • 用户登录成功,后端打包用户信息,生成 JWT 令牌发给前端;
  • 前端每次请求带上这个令牌;
  • 后端解析、校验签名,确认没有被篡改,取出登录用户;
  • 项目额外搭配 Redis:用来控制会话过期、强制下线(JWT 本身无状态,没法主动作废)。

JWT的签名是如何生成的

签名 = 头部 + 载荷 + 你的密钥,通过加密算法算出的一串验证码

最终完整 token:header串.payload串.签名串

建议使用SecureRandom生成密钥:

SecureRandom 是密码级别的强随机,不要用普通 Random。

java 复制代码
import java.security.SecureRandom;
import java.util.Base64;

public class JwtSecretGen {
    public static void main(String[] args) {
        // HS512 需要 64 字节密钥
        byte[] key = new byte[64];
        new SecureRandom().nextBytes(key);
        String secret = Base64.getEncoder().encodeToString(key);
        System.out.println(secret);
    }
}

也可以使用Linux快速生成:

java 复制代码
openssl rand -base64 64

使用hutool工具包操作JWT

1.引入1依赖

java 复制代码
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>5.8.26</version>
</dependency>

2.生成Token

java 复制代码
import cn.hutool.jwt.JWTUtil;
import java.util.HashMap;
import java.util.Map;

public class Test {
    // HS512密钥,生产环境64字节以上
    private static final byte[] SECRET = "你的随机密钥".getBytes();

    public static void main(String[] args) {
        Map<String,Object> payload = new HashMap<>();
        payload.put("userId",1001);
        payload.put("username","admin");
        // 过期时间:24小时(毫秒)
        payload.put("expire_time",System.currentTimeMillis() + 24*3600*1000);

        // 创建令牌
        String token = JWTUtil.createToken(payload,SECRET);
        System.out.println(token);
    }
}

3.校验签名,过期时间

java 复制代码
// 校验签名合法性、检查是否过期
boolean ok = JWTUtil.verify(token,SECRET);

4.解析获取载荷中的数据

java 复制代码
JWT jwt = JWTUtil.parseToken(token);
Integer userId = (Integer) jwt.getPayload("userId");
String username = (String) jwt.getPayload("username");

链式写法

java 复制代码
import cn.hutool.core.date.DateUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.signers.JWTSignerUtil;

byte[] secret = "密钥".getBytes();
String token = JWT.create()
        .setPayload("userId",1001)
        .setPayload("username","admin")
        .setIssuedAt(DateUtil.date())          //签发时间
        .setExpiresAt(DateUtil.offsetHour(DateUtil.date(),24)) //过期时间
        .setSigner(JWTSignerUtil.hs512(secret)) //指定HS512加密算法
        .sign();
相关推荐
唐青枫1 小时前
Java JCommander 实战详解:用注解解析命令行参数
java
步行cgn2 小时前
carList.forEach(System.out::println)
java·开发语言·mybatis
plainGeekDev2 小时前
JUnit 4 → JUnit 5 + Kotlin
android·java·kotlin
plainGeekDev2 小时前
Mockito → MockK
android·java·kotlin
Zane19942 小时前
ThreadLocal 与 BlockingQueue:线程本地变量的内存泄漏原理,以及阻塞队列怎么选?
java·后端
用户3126874877202 小时前
Spring Bean 生命周期到底经历了什么?从实例化到销毁的全链路拆解
java·spring boot
Flittly2 小时前
【我的手搓轮子日记】(2)handmade-ioc 手搓 IOC 容器
java·spring boot·spring
阿昌喜欢吃黄桃3 小时前
Dubbo服务重启时注册中心下线不及时问题排查与修复记录
java·rpc·dubbo·问题排查
程序员钟霖3 小时前
【实战版】Spring IOC 控制反转详解
java·后端·spring·maven·intellij-idea