Jwt令牌Token生成实践

jwt简介

JSON Web Token(JWT)是⼀个开放的⾏业标准(RFC 7519),它定义了⼀种简介 的、⾃包含的协议格式,⽤于 在通信双⽅传递json对象,传递的信息经过数字签名 可以被验证和信任。JWT可以使⽤HMAC算法或使⽤RSA的公 钥/私钥对来签名,防 ⽌被篡改。

最佳实践:

在使用jwt时,我们可以向jwt令牌中存放我们用户自定义的信息,但是在存放自定义信息时不建议将一些敏感信息存放进去(比如:用户密码,用户手机号,等信息,因为jwt生成的token泄露后,对方可以在jwt网站对该jwt令牌进行解密,得到里面的信息,并且别人在得到jwt令牌后也可以使用这个令牌对我们的系统进行访问,所以在我们的实践中:不会存放用户的敏感信息,然后会在里面存放客户端ip,在客户端来访问时我会检查一下,当前请求的客户端IP和jwt令牌中的ip是否一致,不一致就代表着令牌泄露,可以拒绝访问


		<!--jwt工具类依赖-->       
		<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        

封装的工具类

package org.xhs.utli;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

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

/**
 * @Author: hu.chen
 * @Description:
 * @DateTime: 2022/1/26 5:18 PM
 **/
public class JwtToken {
    
    /**
     *  加密字符串
     */
    private String secret;

    
    public JwtToken(String secret) {
        this.secret = secret;
    }


    /**
     * 生成令牌
     *
     * @param claims     存放进token中的自定义参数(比如:用户名,用户id,客户端ip等等。。。)
     * @param expireTime 当前令牌的过期时间,单位秒
     * @return
     */
    public String generate(Map<String, Object> claims, long expireTime) {
        Date nowDate = new Date();
        //过期时间
        Date expireDate = new Date(nowDate.getTime() + expireTime * 1000);
        if (claims == null) {
            claims = new HashMap<>(8);
        }
        return Jwts.builder()
                //存放自定义值
                .setClaims(claims)
                //当前时间
                .setIssuedAt(nowDate)
                //过期时间
                .setExpiration(expireDate)
                //加密
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 获取jwt令牌失效时间(单位秒)
     */
    public long getExpirationTime(String token) {
        Claims claim = getClaim(token);
        Date expiration = claim.getExpiration();
        long time = (expiration.getTime() - System.currentTimeMillis()) / 1000;
        return time;
    }


    /**
     * 获取jwt令牌生成时间时间
     */
    public Date getIssuedAtTime(String token) {
        Claims claim = getClaim(token);
        return claim.getIssuedAt();
    }


    /**
     * 验证token是否失效
     *
     * @param token
     * @return true:有效   false:无效
     */
    public boolean isExpired(String token) {
        try {
            Claims claim = getClaim(token);
            Date date = new Date();
            final Date expiration = claim.getExpiration();
            return date.before(expiration);
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获取token信息
     *
     * @param token
     * @return
     */
    public Map<String, Object> getTokenInfo(String token) {
        Claims claim = getClaim(token);
        return claim;
    }


    /**
     * 解析Claims
     *
     * @param token
     * @return
     */
    private Claims getClaim(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            claims = e.getClaims();
        }
        return claims;
    }


}

测试:

 public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {

		// 	创建 token 生成器
        JwtToken jwtToken = new JwtToken("nsvnsdfvdh1243nskdvn");

        //生成令牌
        Map<String, Object> claims = new HashMap<>(8);
        //设置自定义值
        claims.put("002", "new Test()");
        claims.put("userName", "chenhu");
        claims.put("password", "123456");
        String generate = jwtToken.generate(claims, 30);
        //打印令牌
        System.err.println(generate);
//       String generate="eyJhbGciOiJIUzUxMiJ9.eyIwMDIiOiJuZXcgVGVzdCgpIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJ1c2VyTmFtZSI6ImNoZW5odSIsImV4cCI6MTY0MzE4OTk2MiwiaWF0IjoxNjQzMTg5OTMyfQ.07Yw-rsQ4MR_kHkZCg8P-fI-ANYJnemRQpnv6sHVv79furxnuqa2Y6V2wVchiESjMm2RL2u2B-s09vIBRaV8aw";

     
        // 验证token是否有效
        System.err.println(jwtToken.isExpired(generate));

     
        // 获取token 还有多长时间失效(单位秒)
        System.err.println(jwtToken.getExpirationTime(generate));

     
        // 获取token 生成时间
        System.err.println(jwtToken.getIssuedAtTime(generate));

        
        // 获取jwt令牌中自定义信息
        Map<String, Object> tokenInfo = jwtToken.getTokenInfo(generate);

        System.err.println(tokenInfo.get("002"));
        System.err.println(tokenInfo.get("userName"));
        System.err.println(tokenInfo.get("password"));
        
    }
上一篇:第二十六章 登录检验解决⽅案 JWT


下一篇:利用JWT生成Token