TokenUtil

该工具类用于生成token和解析token对象

代码


package com.gdpu.util;

import com.gdpu.exception.TokenException;
import com.gdpu.bo.UserTokenBO;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;


/**
 * @author mojiazhu
 * @date 2022/12/10 8:26
 * <p>
 * token工具类 鉴权token JWT由三部分构成{header(base64后的),payload(base64后的),secret组成}
 */

@Slf4j
public class TokenUtil {

    //设置本次请求的threadLocal
    private static final ThreadLocal<UserTokenBO> threadLocal = new ThreadLocal<>();
    //token属性名
    public static final String USER_TOKEN = "Token";
    //加密算法
    public static final Key KEY = Keys.secretKeyFor(SignatureAlgorithm.HS512);
    //过期时间1小时-7天
    private static final Long EXPIRATION = 3600L;
    private static final Long EXPIRATION_REMEMBER = 604800L;


    /**
     * 生成JwtToken
     *
     * @param userTokenBO 用户信息
     * @return JwtToken
     */
    public static String createJwtToken(UserTokenBO userTokenBO, boolean isRememberMe) {
        try {
            Long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
            Map<String, Object> map = new LinkedHashMap<>(5);
            map.put("userId", userTokenBO.getUserId());
            map.put("objectId", userTokenBO.getObjectId());
            map.put("userType", userTokenBO.getUserType());
            log.info("[用户登录]保存用户信息string的字段为:{}", map);

            return Jwts.builder()
                    .setClaims(map)
                    .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                    .signWith(KEY)
                    .compact();
        } catch (Exception e) {
            log.error("[用户登录]生成jwt_token失败,账号为:{}", userTokenBO.getUserId());
            return null;
        }
    }


    /**
     * 验证token是否有效,并返回token的payload
     *
     * @param token
     * @return
     */
    public static boolean verifyJwtToken(String token) {
        try {
            //获取token中的claims对象,获取失败抛出异常
            Claims claims = Jwts.parserBuilder().setSigningKey(KEY).build().parseClaimsJws(token).getBody();
            //将claims转换为UserTokenBO对象
            UserTokenBO userTokenBO = new UserTokenBO();
            userTokenBO.setUserId(claims.get("userId", Double.class).intValue());
            userTokenBO.setObjectId(claims.get("objectId", Double.class).intValue());
            userTokenBO.setUserType(claims.get("userType", Double.class).intValue());
            //将用户信息存在ThreadLocal中
            setUserDetail(userTokenBO);
            return true;
        } catch (Exception e) {
            throw new TokenException("Token验证失败");
        }
    }


    /**
     * 将token解析出来的用户信息自动存在ThreadLocal中
     *
     * @param userTokenBO
     */
    private static void setUserDetail(UserTokenBO userTokenBO) {
        threadLocal.set(userTokenBO);
    }


    /**
     * 获取值
     *
     * @return
     */
    public static UserTokenBO getUserDetail() {
        return threadLocal.get();
    }
}




自定义的token异常

package com.gdpu.exception;

import lombok.extern.slf4j.Slf4j;

/**
 * @author mojiazhu
 * @date 2022/12/10 21:08
 */
@Slf4j
public class TokenException extends RuntimeException {

    public TokenException(String message) {
        super(message);
    }

}

token拦截器

package com.gdpu.interceptor;

import com.gdpu.util.TokenUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author mojiazhu
 * @date 2022/12/10 22:47
 */
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    //忽略拦截的URL
    private String urls[] = {
            "/v2/**"
    };

    /**
     * 进入controller前拦截请求 token验证通过返回true
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String requestURI = request.getRequestURI();
        String token = request.getHeader(TokenUtil.USER_TOKEN);
        String method = request.getMethod();
        if (!"OPTIONS".equals(method)) {
            //遍历需要拦截的路径
            for (String item : this.urls) {
                boolean match = PATH_MATCHER.match(item, requestURI);
                if (match) {
//                    log.info("本次请求不需要拦截,请求地址为:{}", requestURI);
                    return true;
                }
            }
        }
        //检验token
        return TokenUtil.verifyJwtToken(token);

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           @Nullable ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                @Nullable Exception ex) throws Exception {
    }
}

配置token拦截器

package com.gdpu.config;

import com.gdpu.interceptor.TokenInterceptor;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author mojiazhu
 * @date 2022/12/11 1:02
 */
@Configuration
@AllArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {

    private final TokenInterceptor tokenInterceptor;

    /**
     * 注册token拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
    }

}

依赖


<jjwt.version>0.11.2</jjwt.version>

<!-- jjwt,token鉴权 -->
<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-gson</artifactId>
    <version>${jjwt.version}</version>
    <scope>runtime</scope>
</dependency>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚霞虽美不如你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值