jjwt-上手

jjwt-上手

丁起男 301 2021-12-08

jjwt-上手

依赖

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

功能

public interface JwtService {

    /**
     * 获取当前jwt数据加密key
     * @return
     */
    SecretKey generalKey();

    /**
     * 生成一个合法的token数据
     * @param id
     * @param subject
     * @return
     */
    String createToken(String id, Map<String,Object> subject);

    /**
     * 根据token的字符串内容解析出器组成的信息
     * @param token
     * @return 如果token失效或者结构错误
     */
    Jws<Claims> parseToken(String token) throws JwtException;

    /**
     * 校验token是否正确
     * @param token
     * @return
     */
    Boolean verifyToken(String token);

    /**
     * token是有存在时间的定义,所以一定要提供有token刷新机制
     * @param token
     * @return
     */
    String refreshToken(String token);
}

实现

@Service
public class JwtServiceImpl implements JwtService {

    //jwt的相关配置属性
    @Autowired
    private JwtConfigProperties jwtConfigProperties;
    //签名算法
    private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    @Override
    public SecretKey generalKey() {
        //获取密钥
        byte[] encodedKey = jwtConfigProperties.getSecret().getBytes();
        SecretKey key = new SecretKeySpec(encodedKey,0,encodedKey.length,"AES");
        return key;
    }

    @Override
    public String createToken(String id, Map<String, Object> subject) {
        Date now = new Date();//当前时间
        Date expireDate = new Date(now.getTime() + jwtConfigProperties.getExpire() * 1000);//失效时间
        //claims信息
        Map<String,Object> claims = new HashMap<>();
        claims.put("cla","dqn");
        //headers信息
        Map<String,Object> headers = new HashMap<>();
        claims.put("hea","jjwt");
        return Jwts.builder()
                .setClaims(claims)//保存claims信息(解析时得不到)
                .setHeader(headers)//保存header信息
                .setHeaderParam("typ", "JWT")//真正保存在第一部分头部信息
                .setId(id)//保存id jti
                .setIssuedAt(now)//签发时间 iat
                .setIssuer(jwtConfigProperties.getIssuer())//签发人 iss
                .setSubject(JSON.toJSONString(subject))//附加信息 sub
                .signWith(signatureAlgorithm,generalKey())//签名算法 alg
                .setExpiration(expireDate)//token失效时间 exp
                .compact();
    }

    @Override
    public Jws<Claims> parseToken(String token) throws JwtException {
        if (verifyToken(token)){//检查token是否正确
            Jws<Claims> claims = Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token);
            return claims;
        }
        return null;
    }

    @Override
    public Boolean verifyToken(String token) {
        try {
            Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token)
                    .getBody();
            return true;
        }catch (JwtException e){
            return false;//发生异常解析失败
        }
    }

    @Override
    public String refreshToken(String token) {
        if (verifyToken(token)){ //正确的token可以刷新
            Jws<Claims> claimsJws = parseToken(token);//解析
            return createToken(claimsJws.getBody().getId(),
                    JSONObject.parseObject(claimsJws.getBody().getSubject(),Map.class));
        }
        return null;
    }
}