From 077751021e1d853f218c177e90931d67cc44926b Mon Sep 17 00:00:00 2001 From: soul2 <1052986332@qq.com> Date: Mon, 15 Apr 2024 15:42:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A7=A3=E5=AF=86=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jyjc/admin/JavaJyjcAdminApplication.java | 2 - .../{config => bean}/UserLoginStatusBean.java | 4 +- .../soul2/jyjc/admin/config/CorsConfig.java | 28 ------- .../soul2/jyjc/admin/config/WebMvcConfig.java | 45 ++++++++++- .../admin/filter/ReplaceStreamFilter.java | 1 + .../admin/filter/ShaoduoRequestWrapper.java | 14 +--- .../admin/interceptor/FinallyInterceptor.java | 75 ++++++++++--------- .../impl/UserLoginOutRepositoryImpl.java | 2 +- src/main/resources/application-cors.yml | 2 +- 9 files changed, 94 insertions(+), 79 deletions(-) rename src/main/java/cn/soul2/jyjc/admin/{config => bean}/UserLoginStatusBean.java (96%) delete mode 100644 src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java diff --git a/src/main/java/cn/soul2/jyjc/admin/JavaJyjcAdminApplication.java b/src/main/java/cn/soul2/jyjc/admin/JavaJyjcAdminApplication.java index f7af8a4..3b83517 100644 --- a/src/main/java/cn/soul2/jyjc/admin/JavaJyjcAdminApplication.java +++ b/src/main/java/cn/soul2/jyjc/admin/JavaJyjcAdminApplication.java @@ -3,7 +3,6 @@ package cn.soul2.jyjc.admin; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; /** * @author Soul2 @@ -11,7 +10,6 @@ import org.springframework.context.annotation.ComponentScan; */ @SpringBootApplication @MapperScan("cn.soul2.jyjc.admin.mapper") -@ComponentScan("cn.soul2.jyjc.admin.config") public class JavaJyjcAdminApplication { public static void main(String[] args) { diff --git a/src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java b/src/main/java/cn/soul2/jyjc/admin/bean/UserLoginStatusBean.java similarity index 96% rename from src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java rename to src/main/java/cn/soul2/jyjc/admin/bean/UserLoginStatusBean.java index 3937559..99e5446 100644 --- a/src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java +++ b/src/main/java/cn/soul2/jyjc/admin/bean/UserLoginStatusBean.java @@ -1,4 +1,4 @@ -package cn.soul2.jyjc.admin.config; +package cn.soul2.jyjc.admin.bean; import cn.soul2.jyjc.admin.entity.UserLoginOutDO; import org.apache.commons.lang3.StringUtils; @@ -80,7 +80,7 @@ public class UserLoginStatusBean { return Boolean.FALSE; } UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null); - if (loginStatus.getLapseTime() != null) { + if (loginStatus != null && loginStatus.getLapseTime() != null) { LocalDateTime now = LocalDateTime.now(); if (now.isAfter(loginStatus.getLapseTime())) { logout(token); diff --git a/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java b/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java deleted file mode 100644 index 1f56696..0000000 --- a/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.soul2.jyjc.admin.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -/** - * @author Soul2 - * @date 2024-03-25 - */ -@Configuration -public class CorsConfig implements WebMvcConfigurer { - - @Value("${cors.allow-origin}") - private String[] allowOrigin; - - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedHeaders("*") - .allowedOrigins(allowOrigin) - .allowCredentials(true) - .allowedMethods("POST") - .maxAge(3600); - } - -} diff --git a/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java b/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java index 1aa4736..c8329ae 100644 --- a/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java +++ b/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java @@ -1,7 +1,12 @@ package cn.soul2.jyjc.admin.config; import cn.soul2.jyjc.admin.interceptor.FinallyInterceptor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -15,9 +20,47 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { + @Value("${cors.allow-origin}") + private String[] allowOrigin; + + @Bean + public CorsFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + // 设置允许跨域请求的域名 + for (String url : allowOrigin) { + config.addAllowedOrigin(url); + } + // 是否允许证书 不再默认开启 + // config.setAllowCredentials(true); + // 设置允许的方法 + config.addAllowedMethod("*"); + // 允许任何头 + config.addAllowedHeader("*"); + config.addExposedHeader("token"); + config.setMaxAge(3600L); + UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); + configSource.registerCorsConfiguration("/**", config); + return new CorsFilter(configSource); + } + +// @Override +// public void addCorsMappings(CorsRegistry registry) { +// registry.addMapping("/**") +// .allowedHeaders("*") +// .allowedOrigins(allowOrigin) +// .allowCredentials(true) +// .allowedMethods("POST") +// .maxAge(3600); +// } + + @Bean + FinallyInterceptor createFinallyInterceptor() { + return new FinallyInterceptor(); + } + @Override public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new FinallyInterceptor()) + registry.addInterceptor(createFinallyInterceptor()) // 拦截所有路径 .addPathPatterns("/**"); } diff --git a/src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java b/src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java index 8d37d85..0581760 100644 --- a/src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java +++ b/src/main/java/cn/soul2/jyjc/admin/filter/ReplaceStreamFilter.java @@ -27,6 +27,7 @@ public class ReplaceStreamFilter implements Filter { return; } else { ServletRequest requestWrapper = new ShaoduoRequestWrapper((HttpServletRequest) request); +// System.out.printf("ReplaceStreamFilter触发, Method: %s, URI: %s%n", ((HttpServletRequest) request).getMethod(), ((HttpServletRequest) request).getRequestURI()); chain.doFilter(requestWrapper, response); return; } diff --git a/src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java b/src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java index 935de92..a9d539c 100644 --- a/src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java +++ b/src/main/java/cn/soul2/jyjc/admin/filter/ShaoduoRequestWrapper.java @@ -14,7 +14,7 @@ import java.nio.charset.StandardCharsets; /** * @author shaoduo * @description 包装HttpServletRequest,目的是让其输入流可重复读 - * @since 1.0 + * @since shaoduo **/ @Slf4j public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { @@ -23,7 +23,7 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { */ private byte[] body; - public ShaoduoRequestWrapper(HttpServletRequest request) throws IOException { + public ShaoduoRequestWrapper(HttpServletRequest request) { super(request); // 将body数据存储起来 @@ -53,7 +53,6 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { */ public String getBodyString() throws IOException { InputStream inputStream = new ByteArrayInputStream(body); - return inputStream2String(inputStream); } @@ -63,7 +62,6 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { * @param val */ public void setBody(String val) { - body = val.getBytes(StandardCharsets.UTF_8); } @@ -78,7 +76,6 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { BufferedReader reader = null; try { - System.out.println("发生流读取"); reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset())); String line; while ((line = reader.readLine()) != null) { @@ -94,11 +91,8 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { } catch (IOException e) { log.error("", e); } - inputStream.close(); } } - - return sb.toString(); } @@ -108,13 +102,13 @@ public class ShaoduoRequestWrapper extends HttpServletRequestWrapper { } @Override - public ServletInputStream getInputStream() throws IOException { + public ServletInputStream getInputStream() { final ByteArrayInputStream inputStream = new ByteArrayInputStream(body); return new ServletInputStream() { @Override - public int read() throws IOException { + public int read() { return inputStream.read(); } diff --git a/src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java b/src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java index 1f64eae..6109dab 100644 --- a/src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java +++ b/src/main/java/cn/soul2/jyjc/admin/interceptor/FinallyInterceptor.java @@ -2,19 +2,21 @@ package cn.soul2.jyjc.admin.interceptor; import cn.soul2.jyjc.admin.annotation.SkinEncrypt; import cn.soul2.jyjc.admin.annotation.SkinLogin; -import cn.soul2.jyjc.admin.config.UserLoginStatusBean; +import cn.soul2.jyjc.admin.bean.UserLoginStatusBean; import cn.soul2.jyjc.admin.filter.ShaoduoRequestWrapper; import cn.soul2.jyjc.admin.utils.EncryptUtils; +import cn.soul2.jyjc.admin.vo.base.Back; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.MediaType; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; import java.lang.reflect.Method; /** @@ -32,9 +34,8 @@ public class FinallyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean pass = false; - System.out.println("拦截器触发"); // 允许OPTIONS请求通过 - if ("OPTIONS".equals(request.getMethod()) && request.getHeader("Origin") != null) { + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { return true; } // 如果不是映射到方法直接通过 @@ -62,39 +63,31 @@ public class FinallyInterceptor implements HandlerInterceptor { if (request.getContentType() == null) { pass = true; } - // 如果类型不是json 就放行 - if (!(request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE))) { - pass = true; - } } - - // 跳过使用SkinEncrypt注解的情况 + // 跳过使用 @SkinEncrypt 的情况 if (skinEncrypt != null) { pass = true; } - ShaoduoRequestWrapper shaoduoRequestWrapper; - if (request instanceof ShaoduoRequestWrapper) { - shaoduoRequestWrapper = (ShaoduoRequestWrapper) request; - } else { - shaoduoRequestWrapper = new ShaoduoRequestWrapper(request); - request = shaoduoRequestWrapper; - } - String jsonParamBody = shaoduoRequestWrapper.getBodyString(); - JSONObject obj = JSON.parseObject(EncryptUtils.decrypt(jsonParamBody)); - String afterBody = JSONObject.toJSONString(obj); - System.out.println("加密前 " + jsonParamBody); - System.out.println("解密后 " + afterBody); - shaoduoRequestWrapper.setBody(afterBody); - String temp = new ShaoduoRequestWrapper(shaoduoRequestWrapper).getBodyString(); - System.out.println("过滤器中缓存 " + temp); + if (!pass) { + ShaoduoRequestWrapper shaoduoRequestWrapper; + try { + shaoduoRequestWrapper = (ShaoduoRequestWrapper) request; + } catch (Exception e) { + System.out.printf("request.ClassTypeError: %s%n", request.getClass().getName()); + return true; + } + String sourceParamBody = shaoduoRequestWrapper.getBodyString(); + JSONObject obj = JSON.parseObject(EncryptUtils.decrypt(sourceParamBody)); + String afterBody = JSONObject.toJSONString(obj); + shaoduoRequestWrapper.setBody(afterBody); + log.info(String.format("解密: %s -> %s", sourceParamBody, afterBody)); - /* - token验证 - */ + } + /* token验证 */ if (hasSkinLogin) { - // 如果存在,绕过拦截器 + // 跳过使用 @SkinLogin 的情况 pass = true; } else { // 验证token @@ -103,16 +96,30 @@ public class FinallyInterceptor implements HandlerInterceptor { // 没有Token,拒绝请求 response.setStatus(40401); pass = false; - } else if (userLoginStatusBean != null && !userLoginStatusBean.containsToken(token)) { - // Token 无效,拒绝请求 - response.setStatus(40401); - pass = false; + } else if (userLoginStatusBean != null) { + if (!userLoginStatusBean.containsToken(token)) { + // Token 无效,拒绝请求 + response.setStatus(0); + Back back = new Back().setCode(40401).setMessage("Token invalid!"); + + // 转换为 JSON 字符串 + ObjectMapper objectMapper = new ObjectMapper(); + String responseBody = objectMapper.writeValueAsString(back); + + // 输出错误信息到响应中 + PrintWriter writer = response.getWriter(); + writer.print(responseBody); + writer.flush(); + pass = false; + } else { + // token存在, 通过拦截器 + pass = true; + } } } } catch (Exception e) { throw new RuntimeException(e); } - return pass; } diff --git a/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java index 356e10a..84eed82 100644 --- a/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java +++ b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java @@ -1,6 +1,6 @@ package cn.soul2.jyjc.admin.repository.impl; -import cn.soul2.jyjc.admin.config.UserLoginStatusBean; +import cn.soul2.jyjc.admin.bean.UserLoginStatusBean; import cn.soul2.jyjc.admin.dto.UserLoginDTO; import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO; import cn.soul2.jyjc.admin.dto.UserLogoutDTO; diff --git a/src/main/resources/application-cors.yml b/src/main/resources/application-cors.yml index 4db7a92..aaf916b 100644 --- a/src/main/resources/application-cors.yml +++ b/src/main/resources/application-cors.yml @@ -1,7 +1,7 @@ # 允许跨域的地址 cors: - allow-origin: http://localhost + allow-origin: http://localhost:6100, http://localhost:7620 --- spring: