欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java jjwt-api使用,java jwt使用,java jwt 工具类

程序员文章站 2022-07-13 07:59:04
...

java jjwt-api使用,java jwt使用,java jwt 工具类,Java Web Token工具类

Springboot jwt整合

 

================================

©Copyright 蕃薯耀 2020-12-02

http://fanshuyao.iteye.com/

 

一、引入jjwt-api依赖

<properties>
    <!-- 构建时编码 -->    
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 输出时编码 -->
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <!-- JDK版本 -->
    <java.version>1.8</java.version>
    <jjwt.version>0.11.2</jjwt.version>
</properties>

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>${jjwt.version}</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>${jjwt.version}</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>${jjwt.version}</version>
    <scope>runtime</scope>
</dependency>

 

 

二、 jjwt-api实现工具类

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.lqy.study.exception.RunException;
import com.lqy.study.utils.DateUtils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.MissingClaimException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.io.Decoders;

@Component
public class JwtUtils {

    private static Logger log = Logger.getLogger(JwtUtils.class);
    
    
    private static String secretKey;
    
    private static String aa;//测试静态变量注入
    
    /**
     * 静态变量注入
     * 从配置文件读取jjwt.key属性
     * 注入key,set方法不能是static
     * @param secretKey
     */
    @Value("${jjwt.key}")
    public void setSecretKey(String secretKey) {
        JwtUtils.secretKey = secretKey;
    }
    
    
    /**
     * 静态实体变量注入
     * jjwtProperties需要配置:@ConfigurationProperties(prefix = "jjwt", ignoreUnknownFields = true)
     * @param jjwtProperties
     */
    @Autowired
    public void setSecretKey(JjwtProperties jjwtProperties) {
        JwtUtils.aa = jjwtProperties.getKey();
    }


    private static String KEY_CLAIMS = "key_claims";
    private static String SUBJECT = "key_subject";
    
    private JwtUtils(){
        
    }
    
    
    /**
     * 生成token
     * @return
     * @throws ParseException
     */
    public static String getToken() throws ParseException {
        //Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        
        log.info("aa===" + aa);
        
        
        Date now = new Date();
        Date expirationDate = DateUtils.addMinute(null, 2);//增加2分钟的过期时间,用于测试
        
        log.info("now===" + DateUtils.formatDateTime(now));
        log.info("expirationDate===" + DateUtils.formatDateTime(expirationDate));
        
        Map<String, Object> claims = new HashMap<String, Object>();
        User user = new User();
        user.setId(1000L);
        user.setName("张三");
        claims.put(KEY_CLAIMS, user);
        
        String token = Jwts.builder()
                        .setClaims(claims)//必须放最前面,不然后面设置的东西都会没有:如setExpiration会没有时间
                        .setId(UUID.randomUUID().toString())
                        .setSubject(SUBJECT)
                        .setIssuedAt(now)
                        .setExpiration(expirationDate)//过期时间
                        .signWith(SignatureAlgorithm.HS256, getSecretKey())
                        .compact();
        
        log.info("token===" + token);
        
        return token;
    }
    
    
    /**
     * 解析token,并返回User对象
     * @param token
     * @return
     * @throws ParseException
     */
    public static User parseToken(String token) throws ParseException {
        
        String msg = null;
        try {
            Jws<Claims> jws = Jwts.parser()
                    .setSigningKey(getSecretKey())
                    .requireSubject(SUBJECT)//校验必须有这个属性,可以省略这步
                    .parseClaimsJws(token);
    
            Claims claims = jws.getBody();//Claims是一个Map
            
            log.info("claims===" + JSONUtil.toJsonStr(claims));
            log.info("claims.getIssuedAt()===" + claims.getIssuedAt());
            log.info("claims.getExpiration()===" + claims.getExpiration());
            
            //map转实体
            User user = BeanUtil.toBean(claims.get(KEY_CLAIMS), User.class);
            log.info("user===" + JSONUtil.toJsonStr(user));
            
            return user;
            
            
        }catch (SignatureException se) {
            msg = "密钥错误";
            log.error(msg, se);
            throw new RunException(msg);
            
        }catch (MalformedJwtException me) {
            msg = "密钥算法或者密钥转换错误";
            log.error(msg, me);
            throw new RunException(msg);
            
        }catch (MissingClaimException mce) {
            msg = "密钥缺少校验数据";
            log.error(msg, mce);
            throw new RunException(msg);
            
        }catch (ExpiredJwtException mce) {
            msg = "密钥已过期";
            log.error(msg, mce);
            throw new RunException(msg);
            
        }catch (JwtException jwte) {
            msg = "密钥解析错误";
            log.error(msg, jwte);
            throw new RunException(msg);
        }
        
    }
    
    
    /**
     * 获取自定义密钥
     * @return
     */
    private static byte[] getSecretKey() {
        //log.info("secretKey = " + secretKey);
        if(StringUtils.isBlank(secretKey)) {
            throw new RunException("jjwt配置的密钥不能为空");
        }
        return Decoders.BASE64.decode(secretKey);
    }
    
    
    public static void main(String[] args) throws Exception {
        getToken();
    }

    
}

 

 

User类:

public class User {

    private Long id;
    private String name;
    
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}

 

三、科普springboot静态变量注入的方式

1、静态变量secretKey通过配置文件application.properties的属性注入,并使用base64编码,取出来的时候,需要解码(配置文件的属性也可以不编码,直接取出来)

jjwt.key=aXNsZWVfaGFoYQ==

 

注入方式:方法加注解@Value("${jjwt.key}"),变量作为参数

/**
 * 静态变量注入
 * 从配置文件读取jjwt.key属性
 * 注入key,set方法不能是static
 * @param secretKey
 */
@Value("${jjwt.key}")
public void setSecretKey(String secretKey) {
    JwtUtils.secretKey = secretKey;
}

 

 

2、静态实体变量 jjwtProperties 注入,同样通过通过配置文件application.properties的属性注入,但可以直接配置多个属性(仅用于学习,可忽略):

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "jjwt", ignoreUnknownFields = true)
public class JjwtProperties {

    private String key;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

 

注入的方式:方法加上@Autowired注解,实体作为参数

/**
 * 静态实体变量注入
 * jjwtProperties需要配置:@ConfigurationProperties(prefix = "jjwt", ignoreUnknownFields = true)
 * @param jjwtProperties
 */
@Autowired
public void setSecretKey(JjwtProperties jjwtProperties) {
    JwtUtils.aa = jjwtProperties.getKey();
}

 

 

 springboot 整合java-jwt,见:

 https://www.iteye.com/blog/fanshuyao-2517923

 

================================

©Copyright 蕃薯耀 2020-12-02

http://fanshuyao.iteye.com/