<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.2</version>
</dependency>
pom中新增以上依赖
2.新建jwt生成的工具类
package com.springboot.boot.trial.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.auth0.jwt.interfaces.Verification;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @Author 康露
* @Date 2023/4/18 0018 9:00
* Jwt Token 生成的工具类
*/
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtil {
/**
* 定义 token 返回头部
*/
public static String header;
/**
* token 前缀
*/
public static String tokenPrefix;
/**
* 签名密钥
*/
public static String secret;
/**
* 有效期
*/
public static long expireTime;
/**
* 存进客户端的 token 的 key 名
*/
public static final String USER_LOGIN_TOKEN = "token";
/**
* 设置 token 头部
* @param header token 头部
*/
public void setHeader(String header) {
JwtUtil.header = header;
}
/**
* 设置 token 前缀
* @param tokenPrefix token 前缀
*/
public void setTokenPrefix(String tokenPrefix) {
JwtUtil.tokenPrefix = tokenPrefix;
}
/**
* 设置 token 密钥
* @param secret token 密钥
*/
public void setSecret(String secret) {
JwtUtil.secret = secret;
}
/**
* 设置 token 有效时间
* @param expireTimeInt token 有效时间
*/
public void setExpireTime(int expireTimeInt) {
JwtUtil.expireTime = expireTimeInt;
}
/**
* 创建 TOKEN
* JWT 构成: header, payload, signature
* @param sub jwt 所面向的用户,即用户名
* @return token 值
*/
public static String createToken(String sub) {
return tokenPrefix + JWT.create()
.withSubject(sub)
.withExpiresAt(new Date(System.currentTimeMillis() + expireTime))
.sign(Algorithm.HMAC512(secret));
}
/**
* 验证 token
* @param token 验证的 token 值
* @return 用户名
*/
public static String validateToken(String token) throws Exception {
try {
Verification verification = JWT.require(Algorithm.HMAC512(secret));
JWTVerifier jwtVerifier = verification.build();
// 去除 token 的前缀
String noPrefixToken = token.replace(tokenPrefix, "");
DecodedJWT decodedJwt = jwtVerifier.verify(noPrefixToken);
if(decodedJwt != null) {
return decodedJwt.getSubject();
}
return "";
} catch (TokenExpiredException e){
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
return "";
}
return "";
}
/**
* 检查 token 是否需要更新
* @param token token 值
* @return 过期时间
*/
public static boolean isNeedUpdate(String token) throws Exception {
// 获取 token 过期时间
Date expiresAt = null;
try {
expiresAt = JWT.require(Algorithm.HMAC512(secret))
.build()
.verify(token.replace(tokenPrefix, ""))
.getExpiresAt();
} catch (TokenExpiredException e){
return true;
} catch (Exception e){
throw new Exception(("token 验证失败"));
}
// 需要更新
return (expiresAt.getTime() - System.currentTimeMillis()) < (expireTime >> 1);
}
}
过滤器
package com.springboot.boot.trial.filter;
import com.alibaba.fastjson.JSONObject;
import com.springboot.boot.trial.util.JwtUtil;
import com.springboot.utils.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* * @Author 康露
* * @Date 2023/4/18 0018 10:45
* URL拦截,做对应处理
*
*/
@Component
public class URLInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(URLInterceptor.class);
/**
* 请求前置处理(后置处理同理)
*
* @param request
* @param response
* @param handler
* @return boolean
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String path = request.getServletPath();
//此处设置过滤
String pattern = "trialLogin";
//String pattern = "getPostList";
System.out.println("paht:"+path);
if (path.contains(pattern)) {
//登录接口放行
if(path.contains("doLogin")){
return true;
}
//logger.info("requestUrl: {}", path);
System.out.println(path.contains(pattern));
// 从 request 的 header 中获得 token 值
String token = request.getHeader("authorization");
if (token == null || token.equals("")) {
//重置response
response.reset();
//设置编码格式
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write(JSONObject.toJSONString(new Result(Result.ERROR, "无token,请重新登录", null)));
pw.flush();
pw.close();
return false;
}
// 验证 token, JwtUtil 是自己定义的类,里面有个方法验证 token
String sub = JwtUtil.validateToken(token);
if (sub == null || sub.equals("")) {
//重置response
response.reset();
//设置编码格式
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write(JSONObject.toJSONString(new Result(Result.ERROR, "token验证失败,请重新登录", null)));
pw.flush();
pw.close();
return false;
}
// 更新 token 有效时间
if (JwtUtil.isNeedUpdate(token)) {
// 过期就创建新的 token 给前端
String newToken = JwtUtil.createToken(sub);
response.setHeader(JwtUtil.USER_LOGIN_TOKEN, newToken);
}
// 进行前置处理
return true;
// 或者 return false; 禁用某些请求
} else {
return true;
}
}
}
拦截器注入
package com.springboot.boot.trial.config;
import com.springboot.boot.trial.filter.URLInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 拦截器注入
* @Author 康露
* @Date 2023/4/18 0018 10:48
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private URLInterceptor urlInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(urlInterceptor);
}
}