JWT 生成

本文介绍了JWT(JSON Web Token)的生成与解析过程。在快速入门部分,讲述了如何在SpringBoot环境中配置JWT。JWT简介中详细阐述了JWT的三个组成部分:Header、Payload和Signature,并解释了Payload中各标准声明的含义。同时,文中还提到了如何生成和解析Token的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jwt Token生成

JWT的原则是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户

一、快速入门

  1. 搭建SpringBoot环境

  2. pom.xml 中添加 java-jwt

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
    
  3. application.yml 中添加 token 设置

token:
    # 令牌自定义标识
    header: Authorization
    # 令牌密钥
    secret: 123
    # 令牌有效期(默认30分钟)
    expireTime: 30
  1. 实现Token服务类
@Component
@Service
public class ManufactoryTokenService{
    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    // 令牌有效期
    @Value("${token.expireTime}")
    private int expireTime;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
    @Autowired
    private RedisCache redisCache;
    /**
     * 创建令牌 ..不完整代码
     * 创建token原理:随机生成一个不会重复的key;然后以键值对的方式将用户数据,存储到redis里边
     * 之后我们将这个唯一的key加密生成token信息,我们从前端获取到token后解析成原本的key,
     * 最后到redis里边就可以找到保存的登录用户数据了
     * @param loginUser 用户信息
     * @return 令牌
     */
    public String createToken(User user){
        String token = IdUtil.fastUUID();
        user.setToken(token);
        setUserAgent(user); // 设置数据;
        refreshToken(user);
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, token);
        return createToken(claims);
    }


}

二、JWT 简介

1. JWT 秘钥组成

  • Header(头部) —— base64编码的Json字符串

    • 声明类型,一般都是JWT
    • 声明加密算法
    {
      'typ': 'JWT',
      'alg': 'HS256'
    }
    
  • Payload(载荷) —— base64编码的Json字符串

    • 标准中注册的声明 (建议但不强制使用) :
    • iss: jwt签发者
    • sub: jwt所面向的用户
    • aud: 接收jwt的一方
    • exp: jwt的过期时间,这个过期时间必须要大于签发时间
    • nbf: 定义在什么时间之前,该jwt都是不可用的.
    • iat: jwt的签发时间
    • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    • 公共的声明可以添加任何的信息
  • Signature(签名)—— 使用指定算法,通过Header和Payload加盐计算的字符串

    • header (base64后的)
    • payload (base64后的)
    • secret 秘钥
    • 将这三个部分组合进行加密
eyJhbGciOiJIUzUxMiJ9.eyJjcnQiOjE1MjgzNDM4OTgyNjgsImV4cCI6MTUyODM0MzkxOCwidXNlcm5hbWUiOiJ0b20ifQ.E-0jxKxLICWgcFEwNwQ4pfhdMzchcHmsd8G_BTsWgkUmVwPzDd7jJlf94cAdtbwTLMm27ouYYzTTxMXq7W1jvQ
  • 以点分开每个部分,base64编码组成的是可以反编译回去的

2. 生成Token

private String createToken(Map<String, Object> claims){
        JwtBuilder token = Jwts.builder();
        token.setClaims(claims);
        String compact = token.signWith(SignatureAlgorithm.HS512, secret).compact();
        return compact;
}
  • 生成token 我们一般用 Jwts.builder() 创建一个 JwtBuilder 对象;
  • JwtBuilder 里边常用属性
  private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private Header header; //头部
    private Claims claims; //声明
    private String payload; //载荷
    private SignatureAlgorithm algorithm; //签名算法
    private Key key; //签名key
    private byte[] keyBytes; //签名key的字节数组
    private CompressionCodec compressionCodec; //压缩算法

3. 解析Token

private static Claims getClaimsFromToken(String token) {
    Claims claims;
    try {
        claims = Jwts.parser()
            .setSigningKey(secret)
            .parseClaimsJws(token)
            .getBody();
    } catch (Exception e) {
        claims = null;
    }
    return claims;
}	
  • 通过 Jwts.parser() 返回的是一个 JwtParser对象;即DefaultJwtParser对象
private static final String ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final int MILLISECONDS_PER_SECOND = 1000;
private ObjectMapper objectMapper = new ObjectMapper();

private byte[] keyBytes; //签名key字节数组
private Key key; //签名key
private SigningKeyResolver signingKeyResolver; //签名Key解析器
private CompressionCodecResolver compressionCodecResolver = new DefaultCompressionCodecResolver(); //压缩解析器
Claims expectedClaims = new DefaultClaims(); //期望Claims
private Clock clock = DefaultClock.INSTANCE; //时间工具实例
private long allowedClockSkewMillis = 0;  //允许的时间偏移量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

StarLightLu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值