Jwt 工具类

Jwt 工具类

这里主要是记录Jwt 常用的一些工具类,方便以后查阅!!!

一、Jwt工具类

(一)、静态工具类

JwtTokenUtil

package com.wl.cloud.security.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.wl.cloud.core.utils.CustomServletUtils;
import com.wl.cloud.security.config.JwtProperties;
import com.wl.cloud.security.model.LoginUserDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetails;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: wanglin
 * @date: 2023-09-12 周二
 * @Version: 1.0
 * @Description: JwtToken生成的工具类
 * JWT token的格式:header.payload.signature
 * header的格式(算法、token的类型):
 * {"alg": "HS512","typ": "JWT"}
 * payload的格式(用户名、创建时间、生成时间):
 * {"sub":"wang","created":1489079981393,"exp":1489684781}
 * signature的生成算法:
 * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),JwtParamsConfig.secret)
 */
public class JwtTokenUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    /**
     * 获取请求token
     */
    public static String getToken() {
        return getToken(CustomServletUtils.getRequest());
    }

    /**
     * 根据request获取请求token
     */
    public static String getToken(HttpServletRequest request) {
        // 从header获取token标识
        String token = request.getHeader(JwtProperties.tokenHeader);
        return replaceTokenPrefix(token);
    }

    /**
     * 裁剪token前缀,判断token是否是以 'Bearer ' 开头
     */
    public static String replaceTokenPrefix(String token) {
        // 如果前端设置了令牌前缀,则裁剪掉前缀
        if (StringUtils.isNotEmpty(token) && token.startsWith(JwtProperties.tokenHead)) {
            token = token.replaceFirst(JwtProperties.tokenHead, "");
        }
        return token;
    }

    /**
     * 根据request获取请求token
     */
    public static String getRefreshToken(HttpServletRequest request) {
        return request.getHeader(JwtProperties.refreshHeader);
    }

    /**
     * 根据负责生成JWT的token
     */
    private static String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, JwtProperties.secret)
                .compact();
    }

    /**
     * 根据用户信息生成token
     */
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>(16);
        claims.put(SecurityConstants.DETAILS_USERNAME, userDetails.getUsername());
        claims.put(SecurityConstants.CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }

    /**
     * 根据用户信息生成token
     */
    public static String generateToken(LoginUserDetails loginUserDetails) {
        Map<String, Object> claims = new HashMap<>(16);
        claims.put(SecurityConstants.USER_KEY, loginUserDetails.getToken());
        claims.put(SecurityConstants.DETAILS_USERNAME, loginUserDetails.getUsername());
        loginUserDetails.setExpireTime((JwtProperties.expiration * MILLIS_MINUTE) + System.currentTimeMillis());
        return generateToken(claims);
    }

//    /**
//     * 根据用户信息生成token
//     */
//    public static String generateToken(LoginUser loginUser) {
//        Map claims = new HashMap<>(16);
//        claims.put(SecurityConstants.USER_KEY, loginUser.getToken());
//        claims.put(SecurityConstants.DETAILS_USER_ID, loginUser.getUserId());
//        claims.put(SecurityConstants.DETAILS_USERNAME, loginUser.getUsername());
//        loginUser.setExpireTime(JwtParamsConfig.expiration * MILLIS_MINUTE);
//        return generateToken(claims);
//    }

    /**
     * 生成token的过期时间
     */
    private static Date generateExpirationDate() {
        return new Date(System.currentTimeMillis() + JwtProperties.expiration * MILLIS_MINUTE);
    }

    /**
     * 从token中获取登录用户名
     */
    public String getUserNameFromToken(String token) {
        String username;
        try {
            Claims claims = parseToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }

    /**
     * 验证token是否还有效
     *
     * @param token       客户端传入的token
     * @param userDetails 从数据库中查询出来的用户信息
     */
    public static boolean validateToken(String token, UserDetails userDetails) {
        String username = getUserName(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    /**
     * 验证token是否还有效
     *
     * @param token    客户端传入的token
     * @param username 从数据库中查询出来的用户信息
     */
    public static boolean validateToken(String token, String username) {
        String name = getUserName(token);
        return username.equals(name) && !isTokenExpired(token);
    }

    /**
     * 判断token是否已经失效
     */
    public static boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return ObjUtil.isNotNull(expiredDate) ? expiredDate.before(new Date()) : true;
    }

    /**
     * 从token中获取过期时间
     */
    private static Date getExpiredDateFromToken(String token) {
        Claims claims = parseToken(token);
        return ObjUtil.isNotNull(claims) ? claims.getExpiration() : null;
    }

    /**
     * 当原来的token没过期时是可以刷新的
     *
     * @param token
     */
    public String refreshToken(String token) {
        if (StrUtil.isEmpty(token)) {
            return null;
        }
        //如果token已经过期,不支持刷新
        if (isTokenExpired(token)) {
            return null;
        }
        //token校验不通过
        Claims claims = parseToken(token);
        if (claims == null) {
            return null;
        }
        //如果token在30分钟之内刚刷新过,返回原token
        if (tokenRefreshJustBefore(token, 30 * 60)) {
            return token;
        } else {
            claims.put(SecurityConstants.CLAIM_KEY_CREATED, new Date());
            return generateToken(claims);
        }
    }


    /**
     * 当原来的token没过期时是可以刷新的
     *
     * @param oldToken 带tokenHead的token
     */
    public String refreshHeadToken(String oldToken) {
        if (StrUtil.isEmpty(oldToken)) {
            return null;
        }
        String token = oldToken.substring(JwtProperties.tokenHead.length());
        if (StrUtil.isEmpty(token)) {
            return null;
        }
        //如果token已经过期,不支持刷新
        if (isTokenExpired(token)) {
            return null;
        }
        //token校验不通过
        Claims claims = parseToken(token);
        if (claims == null) {
            return null;
        }
        //如果token在30分钟之内刚刷新过,返回原token
        if (tokenRefreshJustBefore(token, 30 * 60)) {
            return token;
        } else {
            claims.put(SecurityConstants.CLAIM_KEY_CREATED, new Date());
            return generateToken(claims);
        }
    }

    /**
     * 判断token在指定时间内是否刚刚刷新过
     *
     * @param token 原token
     * @param time  指定时间(秒)
     */
    private boolean tokenRefreshJustBefore(String token, int time) {
        Claims claims = parseToken(token);
        Date created = claims.get(SecurityConstants.CLAIM_KEY_CREATED, Date.class);
        Date refreshDate = new Date();
        //刷新时间在创建时间的指定时间内
        if (refreshDate.after(created) && refreshDate.before(DateUtil.offsetSecond(created, time))) {
            return true;
        }
        return false;
    }

    /**
     * 判断token在指定时间内是否刚刚刷新过
     *
     * @param claims 原claims
     * @param time   指定时间(秒)
     */
    private boolean tokenRefreshJustBefore(Claims claims, int time) {
        Date created = claims.get(SecurityConstants.CLAIM_KEY_CREATED, Date.class);
        Date refreshDate = new Date();
        //刷新时间在创建时间的指定时间内
        if (refreshDate.after(created) && refreshDate.before(DateUtil.offsetSecond(created, time))) {
            return true;
        }
        return false;
    }

    /**
     * 从令牌中获取数据声明,从token中获取JWT中的负载
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims parseToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser().setSigningKey(JwtProperties.secret).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            LOGGER.error("Token已过期:{}", token);
        } catch (Exception e) {
            LOGGER.error("Token解析失败:{}", token);
        }
        return claims;
    }

    /**
     * 从token中获取JWT中的负载
     *
     * @param token
     * @return
     */
    public static Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(JwtProperties.secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            LOGGER.error("Token解析失败:{}", token);
        }
        return claims;
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param token 令牌
     * @return 用户ID
     */
    public static String getUserKey(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.USER_KEY);
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param claims 身份信息
     * @return 用户ID*-+
     */
    public static String getUserKey(Claims claims) {
        return getValue(claims, SecurityConstants.USER_KEY);
    }

    /**
     * 根据令牌获取用户ID
     *
     * @param token 令牌
     * @return 用户ID
     */
    public static String getUserId(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }

    /**
     * 根据身份信息获取用户ID
     *
     * @param claims 身份信息
     * @return 用户ID
     */
    public static String getUserId(Claims claims) {
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }

    /**
     * 根据令牌获取用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public static String getUserName(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);
    }

    /**
     * 根据身份信息获取用户名
     *
     * @param claims 身份信息
     * @return 用户名
     */
    public static String getUserName(Claims claims) {
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key    键
     * @return 值
     */
    public static String getValue(Claims claims, String key) {
        if (ObjUtil.isNotNull(claims)) {
            return Convert.toStr(claims.get(key), "");
        }
        return null;
    }

    /**
     * 从token中获取登录用户名
     */
    public String getUserName(HttpServletRequest request) {
        String token = request.getHeader(JwtProperties.tokenHeader);
        //存在token
        String authToken = token;
        if (StringUtils.isNotBlank(token)) {
            //判断token是否是以 'Bearer ' 开头
            if (token.startsWith(JwtProperties.tokenHead)) {
                //截取'Bearer ' 后面的token
                authToken = token.substring(JwtProperties.tokenHead.length());
            }
        }
        return getUserName(authToken);
    }
}

(二)、IOC注入工具类

JwtTokenUtil

package com.wl.cloud.security.starter.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.wl.cloud.security.starter.bean.JwtProperties;
import com.wl.cloud.security.starter.bean.LoginUserDetails;
import com.wl.cloud.security.starter.constant.ConstantsSecurity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: wanglin
 * @date: 2023-11-02 周四
 * @Version: 1.0
 * @Description: JwtToken生成的工具类
 * JWT token的格式:header.payload.signature
 * header的格式(算法、token的类型):
 * {"alg": "HS512","typ": "JWT"}
 * payload的格式(用户名、创建时间、生成时间):
 * {"sub":"wang","created":1489079981393,"exp":1489684781}
 * signature的生成算法:
 * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),jwtProperties.getSecret())
 */
public class JwtTokenUtil {
    private final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private SessionRegistry sessionRegistry;

    protected final long MILLIS_SECOND = 1000L;
    protected final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    /**
     * 获取请求token
     */
    public String getToken() {
        return getToken(ServletUtils.getRequest());
    }

    /**
     * 根据request获取请求token
     */
    public String getToken(HttpServletRequest request) {
        // 从header获取token标识
        String token = request.getHeader(jwtProperties.getTokenHeader());
        return replaceTokenPrefix(token);
    }

    /**
     * 裁剪token前缀,判断token是否是以 'Bearer ' 开头
     */
    public String replaceTokenPrefix(String token) {
        // 如果前端设置了令牌前缀,则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(jwtProperties.getTokenHead())) {
            token = token.replaceFirst(jwtProperties.getTokenHead(), "");
        }
        return token;
    }

    /**
     * 根据request获取请求token
     */
    public String getRefreshToken(HttpServletRequest request) {
        return request.getHeader(jwtProperties.getRefreshHeader());
    }

    /**
     * 根据负责生成JWT的token
     */
    private String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
                .compact();
    }

    /**
     * 根据用户信息生成token
     */
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>(16);
        claims.put(ConstantsSecurity.DETAILS_USERNAME, userDetails.getUsername());
        claims.put(ConstantsSecurity.CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }

    /**
     * 根据用户信息生成token
     */
    public String generateToken(LoginUserDetails loginUserDetails) {
        Map<String, Object> claims = new HashMap<>(16);
        claims.put(ConstantsSecurity.USER_KEY, loginUserDetails.getToken());
        claims.put(ConstantsSecurity.DETAILS_USERNAME, loginUserDetails.getUsername());
        loginUserDetails.setExpireTime((jwtProperties.getExpiration() * MILLIS_MINUTE) + System.currentTimeMillis());
        return generateToken(claims);
    }

    /**
     * 生成token的过期时间
     */
    private Date generateExpirationDate() {
        return new Date(System.currentTimeMillis() + jwtProperties.getExpiration() * MILLIS_MINUTE);
    }

    /**
     * 从token中获取登录用户名
     */
    public String getUserNameFromToken(String token) {
        String username;
        try {
            Claims claims = parseToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }

    /**
     * 验证token是否还有效
     *
     * @param token       客户端传入的token
     * @param userDetails 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, UserDetails userDetails) {
        String username = getUserName(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    /**
     * 验证token是否还有效
     *
     * @param token    客户端传入的token
     * @param username 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, String username) {
        String name = getUserName(token);
        return username.equals(name) && !isTokenExpired(token);
    }

    /**
     * 判断token是否已经失效
     */
    public boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return ObjUtil.isNotNull(expiredDate) ? expiredDate.before(new Date()) : true;
    }

    /**
     * 从token中获取过期时间
     */
    private Date getExpiredDateFromToken(String token) {
        Claims claims = parseToken(token);
        return ObjUtil.isNotNull(claims) ? claims.getExpiration() : null;
    }

    /**
     * 判断token在指定时间内是否刚刚刷新过
     *
     * @param token 原token
     * @param time  指定时间(秒)
     */
    private boolean tokenRefreshJustBefore(String token, int time) {
        Claims claims = parseToken(token);
        Date created = claims.get(ConstantsSecurity.CLAIM_KEY_CREATED, Date.class);
        Date refreshDate = new Date();
        //刷新时间在创建时间的指定时间内
        if (refreshDate.after(created) && refreshDate.before(DateUtil.offsetSecond(created, time))) {
            return true;
        }
        return false;
    }

    /**
     * 判断token在指定时间内是否刚刚刷新过
     *
     * @param claims 原claims
     * @param time   指定时间(秒)
     */
    private boolean tokenRefreshJustBefore(Claims claims, int time) {
        Date created = claims.get(ConstantsSecurity.CLAIM_KEY_CREATED, Date.class);
        Date refreshDate = new Date();
        //刷新时间在创建时间的指定时间内
        if (refreshDate.after(created) && refreshDate.before(DateUtil.offsetSecond(created, time))) {
            return true;
        }
        return false;
    }

    /**
     * 从令牌中获取数据声明,从token中获取JWT中的负载
     *
     * @param token 令牌
     * @return 数据声明
     */
    public Claims parseToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            LOGGER.error("Token已过期:{}", token);
        } catch (Exception e) {
            LOGGER.error("Token解析失败:{}", token);
        }
        return claims;
    }

    /**
     * 从token中获取JWT中的负载
     *
     * @param token
     * @return
     */
    public Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(jwtProperties.getSecret())
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            LOGGER.error("Token解析失败:{}", token);
        }
        return claims;
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param token 令牌
     * @return 用户ID
     */
    public String getUserKey(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, ConstantsSecurity.USER_KEY);
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param claims 身份信息
     * @return 用户ID*-+
     */
    public String getUserKey(Claims claims) {
        return getValue(claims, ConstantsSecurity.USER_KEY);
    }

    /**
     * 根据令牌获取用户ID
     *
     * @param token 令牌
     * @return 用户ID
     */
    public String getUserId(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, ConstantsSecurity.DETAILS_USER_ID);
    }

    /**
     * 根据身份信息获取用户ID
     *
     * @param claims 身份信息
     * @return 用户ID
     */
    public String getUserId(Claims claims) {
        return getValue(claims, ConstantsSecurity.DETAILS_USER_ID);
    }

    /**
     * 根据令牌获取用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public String getUserName(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, ConstantsSecurity.DETAILS_USERNAME);
    }

    /**
     * 根据身份信息获取用户名
     *
     * @param claims 身份信息
     * @return 用户名
     */
    public String getUserName(Claims claims) {
        return getValue(claims, ConstantsSecurity.DETAILS_USERNAME);
    }

    /**
     * 从token中获取登录用户名
     */
    public String getUserName(HttpServletRequest request) {
        String token = request.getHeader(this.jwtProperties.getTokenHeader());
        if (StrUtil.isNotBlank(token) && token.startsWith(this.jwtProperties.getTokenHead())) {
            //截取'Bearer ' 后面的token
            token = token.substring(this.jwtProperties.getTokenHead().length());
        }
        return this.getUserName(token);
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key    键
     * @return 值
     */
    public String getValue(Claims claims, String key) {
        if (ObjUtil.isNotNull(claims)) {
            return Convert.toStr(claims.get(key), "");
        }
        return null;
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser() {
        return getLoginUser(ServletUtils.getRequest());
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = getToken(request);
        return StrUtil.isNotBlank(token) ? this.getLoginUser(token) : null;
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser(String token) {
        if (StrUtil.isBlank(token)) {
            return null;
        } else {
            String userKey = this.getUserKey(token);
            return StrUtil.isNotBlank(userKey) ? this.getLoginUserByUserKey(userKey) : null;
        }
    }

    public List<LoginUserDetails> getAllLoginUsers() {
        return sessionRegistry.getAllPrincipals().stream().map(e -> (LoginUserDetails) e).collect(Collectors.toList());
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUserByUserName(String username) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(username)) {
            List<LoginUserDetails> loginUserList = getAllLoginUsers();
            if (CollUtil.isNotEmpty(loginUserList)) {
                return loginUserList.stream().filter(x -> username.equals(x.getUsername())).findAny().orElse(null);
            }
        }
        return null;
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUserByUserKey(String userKey) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(userKey)) {
            List<LoginUserDetails> loginUserList = getAllLoginUsers();
            if (CollUtil.isNotEmpty(loginUserList)) {
                return loginUserList.stream().filter(x -> userKey.equals(x.getToken())).findAny().orElse(null);
            }
        }
        return null;
    }

    /**
     * 设置用户身份信息
     */
    public void setLoginUser(LoginUserDetails loginUser) {
        if (ObjUtil.isNotNull(loginUser) && StrUtil.isNotEmpty(loginUser.getToken())) {
            refreshToken(loginUser);
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUser(String token) {
        if (StrUtil.isNotEmpty(token)) {
            String userKey = getUserKey(token);
            sessionRegistry.removeSessionInformation(userKey);
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUser(LoginUserDetails loginUser) {
        if (ObjUtil.isNotNull(loginUser)) {
            sessionRegistry.removeSessionInformation(loginUser.getToken());
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUserByUserName(String username) {
        if (StrUtil.isBlank(username)) {
            return;
        }
        List<LoginUserDetails> allLoginUsers = getAllLoginUsers();
        if (CollUtil.isNotEmpty(allLoginUsers)) {
            LoginUserDetails userDetails = allLoginUsers.stream().filter(e -> username.equals(e.getUsername())).findAny().orElse(null);
            if (ObjUtil.isNotNull(userDetails)) {
                sessionRegistry.removeSessionInformation(userDetails.getToken());
            }
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUserByUserKey(String userKey) {
        if (StrUtil.isNotEmpty(userKey)) {
            sessionRegistry.removeSessionInformation(userKey);
        }
    }

    /**
     * 验证令牌有效期,相差不足10分钟,自动刷新缓存
     *
     * @param loginUser
     */
    public void verifyToken(LoginUserDetails loginUser) {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= jwtProperties.getRefreshTime() * MILLIS_MINUTE) {
            refreshToken(loginUser);
        }
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUserDetails loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + jwtProperties.getExpiration() * MILLIS_MINUTE);
        // 根据uuid将loginUser缓存
        sessionRegistry.registerNewSession(loginUser.getToken(), loginUser);
    }
}

二、Jwt 参数类

(一)静态参数

JwtParamsConfig

package com.wl.cloud.security.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;

/**
 * @author: wanglin
 * @date: 2023-10-25 周三
 * @Version: 1.0
 * @Description:
 */
@Data
public class JwtParamsConfig {
    /**
     * 'Bearer ' ,JWT负载中拿到开头
     */
    public static String tokenHead;
    /**
     * 请求头,Authorization,JWT存储的请求头
     */
    public static String tokenHeader;
    /**
     * 请求头,refreshToken,JWT存储的请求头
     */
    public static String refreshHeader;
    /**
     * 私秘钥
     */
    public static String secret;
    /**
     * 过期时间,默认分钟
     */
    public static Long expiration;
    /**
     * 缓存刷新时间,默认分钟,token过期前10分钟之内,刷新token
     */
    public static Long refreshTime;

    @Value("${jwt.tokenHead}")
    public void setTokenHead(String tokenHead) {
        JwtParamsConfig.tokenHead = tokenHead;
    }

    @Value("${jwt.tokenHeader}")
    public void setTokenHeader(String tokenHeader) {
        JwtParamsConfig.tokenHeader = tokenHeader;
    }

    @Value("${jwt.secret}")
    public void setSecret(String secret) {
        JwtParamsConfig.secret = secret;
    }

    @Value("${jwt.expiration}")
    public void setExpiration(Long expiration) {
        JwtParamsConfig.expiration = expiration;
    }

    @Value("${jwt.refreshTime}")
    public void setRefreshTime(Long refreshTime) {
        JwtParamsConfig.refreshTime = refreshTime;
    }
    @Value("${jwt.refreshHeader}")
    public static void setRefreshHeader(String refreshHeader) {
        JwtParamsConfig.refreshHeader = refreshHeader;
    }
}

(二)参数注入

JwtProperties

package com.wl.cloud.security.config;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author: wanglin
 * @date: 2023-11-06 周一
 * @Version: 1.0
 * @Description:
 */
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {
    /**
     * 'Bearer ' ,JWT负载中拿到开头
     */
    public String tokenHead;
    /**
     * 请求头,Authorization,JWT存储的请求头
     */
    public String tokenHeader;
    /**
     * 私秘钥
     */
    public String secret;
    /**
     * 过期时间,默认分钟
     */
    public Long expiration;
    /**
     * 缓存刷新时间,默认分钟,token过期前10分钟之内,刷新token
     */
    public Long refreshTime;

    public String getTokenHead() {
        return tokenHead;
    }

    public void setTokenHead(String tokenHead) {
        this.tokenHead = StrUtil.isNotBlank(tokenHead) ? tokenHead : "Bearer ";
    }

    public String getTokenHeader() {
        return tokenHeader;
    }

    public void setTokenHeader(String tokenHeader) {
        this.tokenHeader = StrUtil.isNotBlank(tokenHeader) ? tokenHeader : "Authorization";
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public Long getExpiration() {
        return expiration;
    }

    public void setExpiration(Long expiration) {
        this.expiration = ObjUtil.isNotNull(expiration) ? expiration : 30L;
    }

    public Long getRefreshTime() {
        return refreshTime;
    }

    public void setRefreshTime(Long refreshTime) {
        this.refreshTime = ObjUtil.isNotNull(refreshTime) ? refreshTime : 10L;
    }
}

(三)内存登录工具类

package com.wl.cloud.security.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.wl.cloud.core.utils.CustomServletUtils;
import com.wl.cloud.core.utils.StringUtils;
import com.wl.cloud.security.config.JwtParamsConfig;
import com.wl.cloud.security.model.LoginUserDetails;
import com.wl.cloud.security.utils.JwtTokenUtil;
import com.wl.cloud.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.session.SessionRegistry;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: wanglin
 * @date: 2023-10-26 周四
 * @Version: 1.0
 * @Description: token验证处理
 */
public class TokenService {

    @Autowired
    private SessionRegistry sessionRegistry;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser() {
        return getLoginUser(CustomServletUtils.getRequest());
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = SecurityUtils.getToken(request);
        return getLoginUser(token);
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUser(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        String userKey = JwtTokenUtil.getUserKey(token);
        if (StrUtil.isNotBlank(userKey)) {
            return getLoginUserByUserKey(userKey);
        }
        return null;
    }

    public List<LoginUserDetails> getAllLoginUsers() {
        return sessionRegistry.getAllPrincipals().stream().map(e -> (LoginUserDetails) e).collect(Collectors.toList());
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUserByUserName(String username) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(username)) {
            List<LoginUserDetails> loginUserList = getAllLoginUsers();
            if (CollUtil.isNotEmpty(loginUserList)) {
                return loginUserList.stream().filter(x -> username.equals(x.getUsername())).findAny().get();
            }
        }
        return null;
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUserDetails getLoginUserByUserKey(String userKey) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(userKey)) {
            List<LoginUserDetails> loginUserList = getAllLoginUsers();
            if (CollUtil.isNotEmpty(loginUserList)) {
                return loginUserList.stream().filter(x -> userKey.equals(x.getToken())).findAny().get();
            }
        }
        return null;
    }

    /**
     * 设置用户身份信息
     */
    public void setLoginUser(LoginUserDetails loginUser) {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
            refreshToken(loginUser);
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUser(String token) {
        if (StringUtils.isNotEmpty(token)) {
            String userKey = JwtTokenUtil.getUserKey(token);
            sessionRegistry.removeSessionInformation(userKey);
        }
    }

    /**
     * 删除用户缓存信息
     */
    public void delLoginUserByUserName(String username) {
        if (StringUtils.isBlank(username)) {
            return;
        }
        List<LoginUserDetails> allLoginUsers = getAllLoginUsers();
        if (CollUtil.isNotEmpty(allLoginUsers)) {
            LoginUserDetails userDetails = allLoginUsers.stream().filter(e -> username.equals(e.getUsername())).findAny().get();
            if (ObjUtil.isNotNull(userDetails)) {
                sessionRegistry.removeSessionInformation(userDetails.getToken());
            }
        }
    }

    /**
     * 验证令牌有效期,相差不足10分钟,自动刷新缓存
     *
     * @param loginUser
     */
    public void verifyToken(LoginUserDetails loginUser) {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= JwtParamsConfig.refreshTime * MILLIS_MINUTE) {
            refreshToken(loginUser);
        }
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUserDetails loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + JwtParamsConfig.expiration * MILLIS_MINUTE);
        // 根据uuid将loginUser缓存
        sessionRegistry.registerNewSession(loginUser.getToken(), loginUser);
    }
}

关注林哥,持续更新哦!!!★,°:.☆( ̄▽ ̄)/$:.°★ 。

你可能感兴趣的:(java,Jwt)