怎么是用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();
相关推荐
Wang's Blog1 分钟前
Java 项目实战: 外卖平台优化-YApi接口管理平台与文档导入导出
java·开发语言·yapi
专业程序开发源6 分钟前
django新闻推荐系统70655-计算机课程设计、毕业设计
java·javascript·spring boot·后端·python·django·课程设计
vx_Biye_Design22 分钟前
springboot一站式旅游管理平台81037-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·课程设计·express·旅游
写后端的胖头鱼27 分钟前
时间复杂度 & 空间复杂度
java·数据结构·算法·时间复杂度·空间复杂度
嵌入式学习菌31 分钟前
ESP32 ModbusTCP 分片缓存
java·后端·spring
vx_Biye_Design32 分钟前
springboot宠物寄养服务预约与监管系统82684-计算机课程设计、毕业设计
java·vue.js·spring boot·elasticsearch·课程设计·express·宠物
程序员小杰@39 分钟前
Spring Boot 常用注解分类速记
java·spring boot·后端
vx_Biye_Design43 分钟前
springboot小学生英语学习APP62773-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·学习·课程设计
吴声子夜歌1 小时前
Nginx应用与运维——Nginx日志管理
java·运维·nginx