基于JWT的Token认证(Java)

懒驴 2021年11月23日 1,837次浏览

JWT简介

JWT是Json web Token的缩写,是目前比较流行的跨域认证解决方案。
JWT的解决方案是,将认证信息返回个客户端,储存在客户端,下次访问其他页面,需要从客户端传递认证信息回服务器端。

JWT原理

JWT原理就是,服务器认证后,生成一个json格式的对象 ,发送个客户端,以后,客户端域服务器通信的时候,都要发回这个json对象,服务器完全靠这个对象认定用户身份,(但肯定不会像上面那样,那么简单的发送一个对象)这样的话,session中就没有数据了,后面更容易实现扩展。
下列为一个JWT数据的样式:

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOm51bGwsImV4cCI6MTYyMTAwODAwMCwiaWF0IjoxNjE4NDY2ODkwfQ._8yIGLQ5qe1x714ThxjMOcHNmV6YT1l-UfM75svL6PULTzG9YXOdchRyEKYKNTKwhcXfUuvjLFW1gCJWvbIWsw

JWT pom.xml导包

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
	<groupId>com.auth0</groupId>
	<artifactId>java-jwt</artifactId>
	<version>2.2.0</version>
</dependency>
<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt</artifactId>
	<version>0.7.0</version>
</dependency>

JWT Token工具类


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/***
 * JWT Token工具类
 * @author 懒驴
 */
public class JwtsTokenTools {
    private static String secret = "a1g2y47dg3dj59fjhhsd7cnewy73j";

    private static Integer ExpirationDay=30;

    /**当前时间**/
    private static Date generateCurrentDate() {
        return new Date(System.currentTimeMillis());
    }
    /**过期时间**/
    @SuppressWarnings("unused")
    private static Date generateExpirationDate() {
        Date now = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        cal.add(java.util.Calendar.DAY_OF_MONTH, ExpirationDay);
        return DateHelper.stringDateToDate(df.format(cal.getTime()));
    }


    /**
     * 初始化生成token的参数
     * @param userId
     * @return String
     */
    public static String generateToken(String userId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", userId);
        return generateToken(claims);
    }

    /**
     * 生成token
     * @param claims
     * @return String
     */
    private static String generateToken(Map<String, Object> claims) {

        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())	//过期时间
                .setIssuedAt(generateCurrentDate())			//当前时间
                .signWith(SignatureAlgorithm.HS512, secret)	//头部信息 第一个参数为加密方式为哈希512  第二个参数为加的盐为secret字符串
                .compact();
    }

    /***
     * 判断token是否可以刷新
     * @param token
     * @param lastPasswordReset
     * @return
     */
    public static Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            final Date iat = claims.getIssuedAt();
            final Date exp = claims.getExpiration();
            if (iat.before(lastPasswordReset) || exp.before(generateCurrentDate())) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /***
     * 刷新Token
     * @param token
     * @return
     */
    public static String refreshToken(String token) {
        String refreshedToken;
        try {
            final Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            refreshedToken = generateToken(claims);
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

    /***
     * 校验Token
     * @param token
     * @return	true/false
     */
    public static boolean verifyToken(String token) {
        boolean result = false;
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            result = true;
        } catch (Exception e) {
            result = false;
        }
        return result;
    }

    /***
     * 根据Token获取用户ID
     */
    public static String getUserIdByToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            return claims.get("sub").toString();
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
    	/***System.out.println(new Date(System.currentTimeMillis()));
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    	Date now = new Date();
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(now);
    	cal.add(java.util.Calendar.DAY_OF_MONTH, 30);
    	System.out.println(DateHelper.stringDateToDate(df.format(cal.getTime())));***/

        //System.out.println(JwtsTools.generateToken("dbb3fddd180c42eda0d7c3e535a69753"));
        //System.out.println("判断Token是否刷新:"+JwtsTools.canTokenBeRefreshed("eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MjEwMDgwMDAsInN1YiI6bnVsbCwiaWF0IjoxNjE4NDY2MTYxfQ.yevvEGNceljfbvju2Mmb4moUtYPrgQBebAX2V0DiNDt75L9X33sr__ITjvefImP9I-BzP1xoO-CWHQGAU31clg", new Date()));
        //System.out.println("刷新Token:"+JwtsTools.refreshToken("eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1OTcyNDgwMDAsInN1YiI6ImRiYjNmZGRkMTgwYzQyZWRhMGQ3YzNlNTM1YTY5NzUzIiwiaWF0IjoxNTk0NzE2MTA3fQ.Dnus9usAwD10-TWDDuCCLurM7dGd2XhxJPQuH7jaTLM9IR-38B481HwK-E4oxXqjUmCrBSXrjZ4exps7XRk9dA"));
        System.out.println("校验Token:"+JwtsTokenTools.verifyToken("eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOm51bGwsImV4cCI6MTYyMTAwODAwMCwiaWF0IjoxNjE4NDY2ODkwfQ._8yIGLQ5qe1x714ThxjMOcHNmV6YT1l-UfM75svL6PULTzG9YXOdchRyEKYKNTKwhcXfUuvjLFW1gCJWvbIWsw"));
        System.out.println("根据Token获取用户ID:"+JwtsTokenTools.getUserIdByToken("eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOm51bGwsImV4cCI6MTYyMTAwODAwMCwiaWF0IjoxNjE4NDY2ODkwfQ._8yIGLQ5qe1x714ThxjMOcHNmV6YT1l-UfM75svL6PULTzG9YXOdchRyEKYKNTKwhcXfUuvjLFW1gCJWvbIWsw"));
    }
}