【springboot系列】springboot整合jwt

概念

JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。

组成

jwt由三部分组成,分别是头部,载荷以及签证。
然后这三部分进行加密,然后用“.”连接在一起
如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
分别为:header(加密).playload(加密).signature(加密)

1、header

头部,由json组成
具体参数如下:

{
  'typ': 'JWT',
  'alg': 'HS256'
}

  • typ:类型
  • alg:加密算法

2、playload

载荷,一般用于存放有效信息,也是以json的格式进行存储
有效信息分为三部分:

  • 标准中注册的声明;

其中,标准中的注册声明分为以下几部分

iss: jwt签发者;
sub: jwt所面向的用户;
aud: 接收jwt的一方;
exp: jwt的过期时间,这个过期时间必须要大于签发时间;
nbf: 定义在什么时间之前,该jwt都是不可用的;
iat: jwt的签发时间;
jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击;
  • 公共的声明;

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。

  • 私有的声明;

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

3、signature

签证,由三部分组成,分别是:header (base64后的);payload (base64后的);secret (密钥);
所以我们在加解密的时候,需要秘钥,一定要保存好

使用

简单使用

1、导入依赖

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

2、工具类编写

主要有两种方式,一种是存储自定义类,一种是存储hashMap

自定义类
1、构建类
package com.walker.third.jwt;

import lombok.Data;
/**
 * 这里的参数可以自己定义,例如我们可以存储用户的id,或者部门id等等
 * 之后我们就可以在token进行获取
 */
@Data
public class TokenData {

    private String name;
    private Integer age;
}

2、工具类
package com.walker.third.jwt;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;

import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    //jwt标识,这里自己可以进行修改
    static String JWT_ID="tokenId";

    //秘钥,也可以将其放在配置文件中
    static String secretKey="fsfdhufwjnqfjnfafa";



    /**
     * 生成token,claims中存放一个类,方便我们在直接获取类进行处理
     */
    public static String genToken(TokenData tokenData,Integer expiredMinute){

        DateTime date = DateUtil.date();

        HashMap<String, Object> claims = new HashMap<>();
        claims.put("data", JSONUtil.toJsonStr(tokenData));

        //构建JwtBuilder
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims) //私有声明,用于存放有效信息
                .setId(JWT_ID) //是JWT的唯一标识
                .setIssuedAt(date) //签发时间
                .signWith(SignatureAlgorithm.HS256, secretKey) //加密算法
                .setExpiration(DateUtil.offsetMinute(date, expiredMinute));//过期时间

        /**
         * compact:压缩,将header,playload,signature压缩成token字符串
         */
        String compact = builder.compact();
        return compact;
    }



    /**
     * 获取tokenData
     */
    public static TokenData getTokenData(String token){
        Claims body;
        try {
            //使用jwt解析器
            body = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            return null;
        }
        //获取到放入的的data
        String data = body.get("data", String.class);
        //将获取到的json转成对应的类
        return JSONObject.parseObject(data,TokenData.class);
    }



}

3、测试
    @Test
    public void genToken2(){
        TokenData tokenData = new TokenData();
        tokenData.setName("waler");
        tokenData.setAge(18);
        String token = JwtUtil.genToken(tokenData, 10);
        System.out.println(token);

        TokenData res = JwtUtil.getTokenData(token);
        System.out.println(res);
    }

返回结果:

eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoie1wibmFtZVwiOlwid2FsZXJcIixcImFnZVwiOjE4fSIsImV4cCI6MTY1Mzk2OTI2OCwiaWF0IjoxNjUzOTY4NjY4LCJqdGkiOiJ0b2tlbklkIn0.i9ioJYoe8k6X4KlXZu2tU0P0Pfl5D0FH-CApWMf3QOg
TokenData(name=waler, age=18)
HashMap存储
1、工具类方法
package com.walker.third.jwt;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;

import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    //jwt标识,这里自己可以进行修改
    static String JWT_ID="tokenId";

    //秘钥,也可以将其放在配置文件中
    static String secretKey="fsfdhufwjnqfjnfafa";


    /**
     * 生成token
     */
    public static String genToken(Map<String,Object> claims,Integer expiredMinute){

        DateTime date = DateUtil.date();

        JwtBuilder builder = Jwts.builder()
                .setClaims(claims) //私有声明,用于存放有效信息
                .setId(JWT_ID) //是JWT的唯一标识
                .setIssuedAt(date) //签发时间
                .signWith(SignatureAlgorithm.HS256, secretKey) //加密算法
                .setExpiration(DateUtil.offsetMinute(date, expiredMinute));//过期时间

        /**
        * compact:压缩,将header,playload,signature压缩成token字符串
        */
        String compact = builder.compact();
        return compact;
    }



    /**
     * 获取claims
     */
    public static Claims getClaims(String token){
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            claims=null;
        }
        return claims;
    }



}

2、测试
@Test
public void genToken(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","walker");
    map.put("age",18);
    String token = JwtUtil.genToken(map, 10);
    System.out.println(token);
    
    Claims claims = JwtUtil.getClaims(token);
    System.out.println(claims);
    }

返回结果:

eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoid2Fsa2VyIiwiZXhwIjoxNjUzOTcwNzAzLCJpYXQiOjE2NTM5NzAxMDMsImFnZSI6MTgsImp0aSI6InRva2VuSWQifQ.08V-cVMsXxFiJW7l9KhM3968Ke7uKeP7jz3fNRG_Ii0
{name=walker, exp=1653970703, iat=1653970103, age=18, jti=tokenId}

如果使用的是返回Claims的,会返回对应的过期时间等其他的信息,所以对于返回,还是可以使用Claims,当然也可以自己进行一定的整理

相关知识

JwtBuilder

image.png
Header 头部
claims:私有声明
sign 签名

claims,包含两种

    JwtBuilder setClaims(Claims var1);
    JwtBuilder setClaims(Map<String, Object> var1);

加密算法

一般有下面这里几种,枚举

public enum SignatureAlgorithm {
    NONE("none", "No digital signature or MAC performed", "None", (String)null, false),
    HS256("HS256", "HMAC using SHA-256", "HMAC", "HmacSHA256", true),
    HS384("HS384", "HMAC using SHA-384", "HMAC", "HmacSHA384", true),
    HS512("HS512", "HMAC using SHA-512", "HMAC", "HmacSHA512", true),
    RS256("RS256", "RSASSA-PKCS-v1_5 using SHA-256", "RSA", "SHA256withRSA", true),
    RS384("RS384", "RSASSA-PKCS-v1_5 using SHA-384", "RSA", "SHA384withRSA", true),
    RS512("RS512", "RSASSA-PKCS-v1_5 using SHA-512", "RSA", "SHA512withRSA", true),
    ES256("ES256", "ECDSA using P-256 and SHA-256", "Elliptic Curve", "SHA256withECDSA", false),
    ES384("ES384", "ECDSA using P-384 and SHA-384", "Elliptic Curve", "SHA384withECDSA", false),
    ES512("ES512", "ECDSA using P-512 and SHA-512", "Elliptic Curve", "SHA512withECDSA", false),
    PS256("PS256", "RSASSA-PSS using SHA-256 and MGF1 with SHA-256", "RSA", "SHA256withRSAandMGF1", false),
    PS384("PS384", "RSASSA-PSS using SHA-384 and MGF1 with SHA-384", "RSA", "SHA384withRSAandMGF1", false),
    PS512("PS512", "RSASSA-PSS using SHA-512 and MGF1 with SHA-512", "RSA", "SHA512withRSAandMGF1", false);

 //..省略其他代码
}

JwtParser jwt解析器

一般用来处理token的解析,能够获取放在playload中的有效信息
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

WalkerShen

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

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

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

打赏作者

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

抵扣说明:

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

余额充值