You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.6 KiB
Java
135 lines
4.6 KiB
Java
package com.supervision.config;
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.json.JSONObject;
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.jwt.JWT;
|
|
import cn.hutool.jwt.JWTUtil;
|
|
import com.supervision.police.dto.user.UserInfoDTO;
|
|
import com.supervision.utils.TokenUtil;
|
|
import jakarta.servlet.http.Cookie;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.lang.Nullable;
|
|
import org.springframework.web.servlet.HandlerInterceptor;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
@Slf4j
|
|
public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
private UserInfoDTO forgeryUser;
|
|
public JwtInterceptor() {
|
|
}
|
|
|
|
public void setForgeryUser(UserInfoDTO forgeryUser) {
|
|
this.forgeryUser = forgeryUser;
|
|
}
|
|
|
|
@Override
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
|
//请求消息头获取用户ID
|
|
String token = findTokenInRequest(request);
|
|
if (StrUtil.isBlank(token)) {
|
|
if (forgeryUser != null){
|
|
JWT jwt = JWTUtil.parseToken(TokenUtil.creatToken(JSONUtil.toJsonStr(forgeryUser)));
|
|
cacheAuth(jwt);
|
|
return true;
|
|
}
|
|
// 如果是swagger来的接口,说明这里是测试的,会伪造一个用户
|
|
String referer = request.getHeader("Referer");
|
|
if (StrUtil.isNotBlank(referer) && StrUtil.contains(referer, "swagger-ui")) {
|
|
cacheAuth(JWTUtil.parseToken(devActiveUser()));
|
|
return true;
|
|
} else {
|
|
throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
|
|
}
|
|
}
|
|
JWT jwt = JWTUtil.parseToken(token);
|
|
// 校验token是否过期,如果过期了,需要提示过期重新登录
|
|
boolean expire = checkTokenExpire(jwt);
|
|
if (expire){
|
|
throw new BusinessException("用户登录已过期,请重新登录", HttpStatus.UNAUTHORIZED.value());
|
|
}
|
|
String cookieToken = findTokenInCookie(request.getCookies());
|
|
if (!StrUtil.equals(cookieToken, token)){
|
|
Cookie tokenCookie = new Cookie("token", token);
|
|
tokenCookie.setMaxAge((int) TokenUtil.EXPIRE_TIME);
|
|
tokenCookie.setPath("/");
|
|
tokenCookie.setAttribute("SameSite", "Lax");
|
|
response.addCookie(tokenCookie);
|
|
}
|
|
cacheAuth(jwt);
|
|
return true;
|
|
}
|
|
|
|
|
|
@Override
|
|
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler,
|
|
@Nullable Exception ex) throws Exception {
|
|
// 请求结束,将用户信息从thread中移除
|
|
clearAuth();
|
|
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
|
|
}
|
|
|
|
private String findTokenInRequest(HttpServletRequest request) {
|
|
String token = request.getHeader("token");
|
|
if (StrUtil.isEmpty(token)) {
|
|
// 尝试从cookie中获取token数据
|
|
token = findTokenInCookie(request.getCookies());
|
|
}
|
|
return token;
|
|
}
|
|
|
|
|
|
private String findTokenInCookie(Cookie[] cookies) {
|
|
if (cookies != null) {
|
|
for (Cookie cookie : cookies) {
|
|
if (cookie.getName().equals("token")) {
|
|
return cookie.getValue();
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 校验token是否过期
|
|
* @param jwt jwt
|
|
* @return true 过期,false未过期
|
|
*/
|
|
private boolean checkTokenExpire(JWT jwt) {
|
|
Object expireTime = jwt.getPayload("expireTime");
|
|
long l = Long.parseLong(String.valueOf(expireTime));
|
|
// 校验是否比当前时间大
|
|
long currentTimeMillis = System.currentTimeMillis();
|
|
return currentTimeMillis > l;
|
|
}
|
|
|
|
|
|
private void cacheAuth(JWT jwt) {
|
|
try {
|
|
JSONObject claimsJson = jwt.getPayload().getClaimsJson();
|
|
ThreadCache.USER.set(claimsJson.toString());
|
|
} catch (Exception e) {
|
|
log.error("用户信息异常", e);
|
|
}
|
|
}
|
|
|
|
private String devActiveUser() {
|
|
Map<String, Object> map = new HashMap<>();
|
|
map.put("id", "1");
|
|
map.put("account", "test");
|
|
map.put("name", "测试");
|
|
return TokenUtil.creatToken(JSONUtil.toJsonStr(map));
|
|
}
|
|
|
|
private void clearAuth() {
|
|
ThreadCache.USER.remove();
|
|
}
|
|
}
|