登录会话拦截优化
This commit is contained in:
10
pom.xml
10
pom.xml
@@ -145,16 +145,6 @@
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.28</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.zyplayer.doc.core.json;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -20,9 +21,11 @@ import java.util.Objects;
|
||||
*/
|
||||
public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
private static SerializeConfig mapping = new SerializeConfig();
|
||||
|
||||
static {
|
||||
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "状态码")
|
||||
private Integer errCode;
|
||||
@ApiModelProperty(value = "返回值说明")
|
||||
@@ -37,46 +40,46 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
private Integer pageSize;
|
||||
@ApiModelProperty(value = "总页数")
|
||||
private Integer totalPage;
|
||||
|
||||
|
||||
public DocResponseJson() {
|
||||
this.errCode = 200;
|
||||
}
|
||||
|
||||
|
||||
public DocResponseJson(Object data) {
|
||||
this.setData(data);
|
||||
this.errCode = 200;
|
||||
}
|
||||
|
||||
|
||||
public DocResponseJson(int errCode, String errMsg) {
|
||||
super();
|
||||
this.errCode = errCode;
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
|
||||
public DocResponseJson(int errCode, String errMsg, Object data) {
|
||||
super();
|
||||
this.setData(data);
|
||||
this.errCode = errCode;
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
|
||||
public DocResponseJson(Integer errCode) {
|
||||
super();
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
|
||||
public Integer getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
public void setErrCode(Integer errCode) {
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
|
||||
public String getErrMsg() {
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
|
||||
public void setErrMsg(String errMsg) {
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
@@ -138,13 +141,13 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提示语
|
||||
*
|
||||
* @return
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static <T> DocResponseJson<T> warn(String errMsg) {
|
||||
return new DocResponseJson<T>(300, errMsg);
|
||||
@@ -153,9 +156,9 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
/**
|
||||
* 错误
|
||||
*
|
||||
* @return
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static <T> DocResponseJson<T> error(String errMsg) {
|
||||
return new DocResponseJson<T>(500, errMsg);
|
||||
@@ -164,31 +167,31 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
/**
|
||||
* 失败
|
||||
*
|
||||
* @return
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static <T> DocResponseJson<T> failure(int errCode, String errMsg) {
|
||||
return new DocResponseJson<T>(errCode, errMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 成功的返回方法
|
||||
*
|
||||
* @return
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static <T> DocResponseJson<T> ok() {
|
||||
return new DocResponseJson<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 成功的返回方法
|
||||
*
|
||||
* @return
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static <T> DocResponseJson<T> ok(Object data) {
|
||||
if (data == null) {
|
||||
@@ -198,7 +201,7 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
responseJson.setData(data);
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
|
||||
public String toJson() {
|
||||
return JSON.toJSONString(this, mapping);
|
||||
}
|
||||
@@ -215,6 +218,7 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
public boolean isOk() {
|
||||
return Objects.equals(this.errCode, 200);
|
||||
}
|
||||
@@ -223,5 +227,5 @@ public class DocResponseJson<T> implements ResponseJson<T> {
|
||||
public String toString() {
|
||||
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -99,14 +99,6 @@
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.zyplayer.doc.data.aspect;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.HttpConst;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.core.util.ThreadLocalUtil;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.utils.BeanUtil;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class AuthAspect {
|
||||
|
||||
@Around(value = "@annotation(com.zyplayer.doc.core.annotation.AuthMan) || @within(com.zyplayer.doc.core.annotation.AuthMan)")
|
||||
public Object authController(ProceedingJoinPoint pjp) throws Throwable {
|
||||
AuthMan authMan = BeanUtil.getAnnotation(pjp, AuthMan.class);
|
||||
ResponseBody responseBody = BeanUtil.getAnnotation(pjp, ResponseBody.class);
|
||||
RestController restController = BeanUtil.getAnnotation(pjp, RestController.class);
|
||||
boolean isResponseBody = (restController != null || responseBody != null);
|
||||
|
||||
Class<?> returnType = ((MethodSignature) pjp.getSignature()).getMethod().getReturnType();
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
String reason = "你访问的内容需要登录,请登录后再试";
|
||||
if (isResponseBody) {
|
||||
return DocResponseJson.failure(HttpConst.TOKEN_TIMEOUT, reason);
|
||||
} else if (returnType.isAssignableFrom(ModelAndView.class)) {
|
||||
HttpServletRequest request = ThreadLocalUtil.getHttpServletRequest();
|
||||
StringBuffer requestURL = request.getRequestURL();
|
||||
String requestURLStr = URLEncoder.encode(requestURL.toString(), "utf-8");
|
||||
return new ModelAndView("redirect:./#/user/login?redirect=" + requestURLStr);
|
||||
} else if (returnType.isAssignableFrom(Map.class)) {
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
}
|
||||
// 判断权限是否足够
|
||||
boolean haveAuth = DocUserUtil.haveAuth(authMan.value());
|
||||
if (haveAuth) {
|
||||
return pjp.proceed();
|
||||
}
|
||||
String reasonStr = "没有操作权限,请联系管理员";
|
||||
if (isResponseBody) {
|
||||
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
|
||||
if (method.getReturnType().equals(ResponseJson.class)) {
|
||||
return DocResponseJson.warn(reasonStr);
|
||||
} else {
|
||||
try {
|
||||
return Class.forName(method.getReturnType().getName()).newInstance();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return authMan.authUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package com.zyplayer.doc.data.config;
|
||||
|
||||
import com.zyplayer.doc.core.json.HttpConst;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 登录和跨域拦截器
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年05月25日
|
||||
*/
|
||||
@Component
|
||||
public class DocLoginOriginInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Value("${zyplayer.doc.manage.originDomainRegex:}")
|
||||
private String originDomainRegex;
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
|
||||
// 清理用户信息
|
||||
DocUserUtil.clean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object haddler, ModelAndView modelAndView) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录请求信息
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
|
||||
// 指定域名可跨域访问
|
||||
if (StringUtils.isNotBlank(originDomainRegex)) {
|
||||
String origin = request.getHeader("Origin");
|
||||
if (StringUtils.isNotBlank(origin) && origin.toLowerCase().matches(originDomainRegex)) {
|
||||
response.setHeader("Access-Control-Allow-Origin", origin); // 允许访问的域
|
||||
response.setHeader("Access-Control-Allow-Methods", "HEAD,GET,POST,PUT,DELETE");// 允许GET、POST的外域请求
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true"); // 允许请求带cookie到服务器
|
||||
response.setContentType("application/json; charset=utf-8"); // 设定JSON格式标准输出、及编码
|
||||
}
|
||||
}
|
||||
// 清理用户信息
|
||||
DocUserUtil.clean();
|
||||
// 设置token
|
||||
String accessToken = getCookieValueByRequest(request, HttpConst.ACCESS_TOKEN);
|
||||
DocUserUtil.setAccessToken(accessToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie
|
||||
*
|
||||
* @param request
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static Cookie getCookieByRequest(HttpServletRequest request, String name) {
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
return null;
|
||||
}
|
||||
Cookie[] cookies = request.getCookies();
|
||||
for (int i = 0; (cookies != null) && (i < cookies.length); i++) {
|
||||
Cookie cookie = cookies[i];
|
||||
if (name.equals(cookie.getName())) {
|
||||
return cookie;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie值
|
||||
*
|
||||
* @param request
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static String getCookieValueByRequest(HttpServletRequest request, String name) {
|
||||
Cookie cookie = getCookieByRequest(request, name);
|
||||
return cookie == null ? null : cookie.getValue();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.zyplayer.doc.data.utils;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BeanUtil {
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static <T extends Annotation> T getAnnotation(JoinPoint pjp, Class<T> t) throws Exception {
|
||||
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
|
||||
T annotation = method.getAnnotation(t);// 方法上定义的
|
||||
if (annotation == null) {
|
||||
annotation = (T) pjp.getSignature().getDeclaringType().getAnnotation(t);// 类上定义的
|
||||
if (annotation == null) {
|
||||
Object target = pjp.getTarget();
|
||||
annotation = target.getClass().getAnnotation(t);// 实现类上定义的
|
||||
if (annotation == null) {
|
||||
Signature sig = pjp.getSignature();
|
||||
if (sig instanceof MethodSignature) {
|
||||
MethodSignature msig = (MethodSignature) sig;
|
||||
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
|
||||
annotation = currentMethod.getAnnotation(t);// 实现类的方法上定义的
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,7 @@ package com.zyplayer.doc.manage.framework.config;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import com.zyplayer.doc.data.config.DocLoginOriginInterceptor;
|
||||
import com.zyplayer.doc.manage.framework.interceptor.RequestInfoInterceptor;
|
||||
import com.zyplayer.doc.manage.framework.interceptor.UserLoginInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
@@ -13,11 +12,11 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -25,12 +24,10 @@ import java.util.List;
|
||||
@Component
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
|
||||
@Resource
|
||||
RequestInfoInterceptor requestInfoInterceptor;
|
||||
@Resource
|
||||
DocLoginOriginInterceptor docLoginOriginInterceptor;
|
||||
|
||||
UserLoginInterceptor userLoginInterceptor;
|
||||
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
@@ -40,12 +37,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
dateFormatter.setLenient(true);
|
||||
registry.addFormatter(dateFormatter);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
|
||||
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
|
||||
List<MediaType> supportedMediaTypes = new ArrayList<>();
|
||||
supportedMediaTypes.add(new MediaType("application", "json", Charset.forName("UTF-8")));
|
||||
supportedMediaTypes.add(new MediaType("application", "json", StandardCharsets.UTF_8));
|
||||
fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
|
||||
FastJsonConfig fastJsonConfig = new FastJsonConfig();
|
||||
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat);
|
||||
@@ -57,12 +54,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(0, fastJsonHttpMessageConverter());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(docLoginOriginInterceptor);
|
||||
registry.addInterceptor(requestInfoInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png",
|
||||
"/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
|
||||
registry.addInterceptor(userLoginInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png", "/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.zyplayer.doc.manage.framework.interceptor;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
/**
|
||||
* 所有bean初始化后执行,bean初始化了,再初始化一些自己的东西
|
||||
*/
|
||||
@Component
|
||||
public class InitServletContextAware implements InitializingBean,ServletContextAware {
|
||||
|
||||
private ServletContext context;
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
ctx();
|
||||
}
|
||||
|
||||
private void ctx(){
|
||||
String ctx = context.getContextPath();
|
||||
if (ctx != null && ctx.trim().length() > 0 && !ctx.trim().equals("/")) {
|
||||
context.setAttribute("ctx", ctx+"/");
|
||||
context.setAttribute("statics", ctx+"/statics/");
|
||||
} else {
|
||||
context.setAttribute("ctx", "/");
|
||||
context.setAttribute("statics", "/statics/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package com.zyplayer.doc.manage.framework.interceptor;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.http.server.HttpServerRequest;
|
||||
import com.zyplayer.doc.core.util.ThreadLocalUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 记录当前请求信息
|
||||
*/
|
||||
@Component
|
||||
public class RequestInfoInterceptor implements HandlerInterceptor {
|
||||
private static final Logger logger = LoggerFactory.getLogger(RequestInfoInterceptor.class);
|
||||
|
||||
private ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 把当前请求记录到下来
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
|
||||
Long startTime = startTimeThreadLocal.get();
|
||||
startTime = Optional.ofNullable(startTime).orElse(System.currentTimeMillis());
|
||||
long totalTime = System.currentTimeMillis() - startTime;// 结束时间
|
||||
String clientIP = ServletUtil.getClientIP(request);
|
||||
logger.info("IP:{},总耗时:{}ms,URI:{}", clientIP, totalTime, request.getRequestURI());
|
||||
ThreadLocalUtil.clean();
|
||||
startTimeThreadLocal.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object haddler, ModelAndView modelAndView) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录请求信息
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
|
||||
response.setContentType("application/json; charset=utf-8"); // 设定JSON格式标准输出、及编码
|
||||
startTimeThreadLocal.set(System.currentTimeMillis());
|
||||
ThreadLocalUtil.setHttpServletRequest(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.zyplayer.doc.manage.framework.interceptor;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.HttpConst;
|
||||
import com.zyplayer.doc.core.util.ThreadLocalUtil;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import org.apache.catalina.util.RequestUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 用户登录拦截
|
||||
*/
|
||||
@Component
|
||||
public class UserLoginInterceptor implements HandlerInterceptor {
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserLoginInterceptor.class);
|
||||
|
||||
@Value("${zyplayer.doc.manage.originDomainRegex:}")
|
||||
private String originDomainRegex;
|
||||
|
||||
private final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
|
||||
Long startTime = startTimeThreadLocal.get();
|
||||
startTime = Optional.ofNullable(startTime).orElse(System.currentTimeMillis());
|
||||
long totalTime = System.currentTimeMillis() - startTime;
|
||||
String clientIP = ServletUtil.getClientIP(request);
|
||||
logger.info("IP:{},总耗时:{}ms,URI:{}", clientIP, totalTime, request.getRequestURI());
|
||||
ThreadLocalUtil.clean();
|
||||
startTimeThreadLocal.remove();
|
||||
// 清理用户信息
|
||||
DocUserUtil.clean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
startTimeThreadLocal.set(System.currentTimeMillis());
|
||||
ThreadLocalUtil.setHttpServletRequest(request);
|
||||
// 指定域名可跨域访问
|
||||
if (StringUtils.isNotBlank(originDomainRegex)) {
|
||||
String origin = request.getHeader("Origin");
|
||||
if (StringUtils.isNotBlank(origin) && origin.toLowerCase().matches(originDomainRegex)) {
|
||||
response.setHeader("Access-Control-Allow-Origin", origin); // 允许访问的域
|
||||
response.setHeader("Access-Control-Allow-Methods", "HEAD,GET,POST,PUT,DELETE");// 允许GET、POST的外域请求
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true"); // 允许请求带cookie到服务器
|
||||
response.setContentType("application/json; charset=utf-8"); // 设定JSON格式标准输出、及编码
|
||||
}
|
||||
}
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
// 清理用户信息
|
||||
DocUserUtil.clean();
|
||||
// 设置token
|
||||
Cookie cookie = ServletUtil.getCookie(request, HttpConst.ACCESS_TOKEN);
|
||||
String accessToken = (cookie == null) ? null : cookie.getValue();
|
||||
DocUserUtil.setAccessToken(accessToken);
|
||||
AuthMan authMan = ((HandlerMethod) handler).getMethod().getAnnotation(AuthMan.class);
|
||||
if (authMan == null) {
|
||||
authMan = ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(AuthMan.class);
|
||||
if (authMan == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
String reason = "你访问的内容需要登录,请登录后再试";
|
||||
DocResponseJson.failure(HttpConst.TOKEN_TIMEOUT, reason).send(response);
|
||||
return false;
|
||||
}
|
||||
// 判断权限是否足够
|
||||
boolean haveAuth = DocUserUtil.haveAuth(authMan.value());
|
||||
if (haveAuth) {
|
||||
return true;
|
||||
}
|
||||
String reasonStr = "没有操作权限,请联系管理员";
|
||||
DocResponseJson.warn(reasonStr).send(response);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import springfox.documentation.swagger.web.SwaggerResource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -76,8 +77,13 @@ public class SwaggerDocumentController {
|
||||
String docUrl = SwaggerDocUtil.replaceSwaggerResources(swaggerDoc.getDocUrl());
|
||||
if (SwaggerDocUtil.isSwaggerResources(docUrl)) {
|
||||
String swaggerDomain = SwaggerDocUtil.getSwaggerResourceDomain(docUrl);
|
||||
String resourcesStr = swaggerHttpRequestService.requestSwaggerUrl(request, docUrl, swaggerDomain);
|
||||
List<SwaggerResource> resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
||||
List<SwaggerResource> resourceList;
|
||||
try {
|
||||
String resourcesStr = swaggerHttpRequestService.requestSwaggerUrl(request, docUrl, swaggerDomain);
|
||||
resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
||||
} catch (Exception e) {
|
||||
return DocResponseJson.warn("解析文档地址失败:" + e.getMessage());
|
||||
}
|
||||
if (resourceList == null || resourceList.isEmpty()) {
|
||||
return DocResponseJson.warn("该地址未找到文档");
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.zyplayer.doc.swaggerplus.controller;
|
||||
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.SwaggerDoc;
|
||||
import com.zyplayer.doc.data.service.manage.SwaggerDocService;
|
||||
import com.zyplayer.doc.swaggerplus.controller.vo.SwaggerResourceVo;
|
||||
@@ -37,6 +38,7 @@ public class SwaggerProxyController {
|
||||
@Resource
|
||||
private SwaggerHttpRequestService swaggerHttpRequestService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/swagger-resources")
|
||||
public List<SwaggerResourceVo> swaggerResources() {
|
||||
List<SwaggerResourceVo> resourceList = new LinkedList<>();
|
||||
@@ -57,15 +59,19 @@ public class SwaggerProxyController {
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/v2/api-docs", produces = {MimeTypeUtils.APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE})
|
||||
public ResponseEntity<Json> content(HttpServletRequest request, Long id) {
|
||||
public ResponseEntity<Object> content(HttpServletRequest request, Long id) {
|
||||
SwaggerDoc swaggerDoc = swaggerDocService.getById(id);
|
||||
if (swaggerDoc == null) {
|
||||
throw new ConfirmException("文档不存在");
|
||||
}
|
||||
if (Objects.equals(swaggerDoc.getDocType(), 1)) {
|
||||
String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(swaggerDoc.getDocUrl());
|
||||
String contentStr = swaggerHttpRequestService.requestSwaggerUrl(request, swaggerDoc.getDocUrl(), docsDomain);
|
||||
return new ResponseEntity<>(new Json(contentStr), HttpStatus.OK);
|
||||
try {
|
||||
String docsDomain = SwaggerDocUtil.getV2ApiDocsDomain(swaggerDoc.getDocUrl());
|
||||
String contentStr = swaggerHttpRequestService.requestSwaggerUrl(request, swaggerDoc.getDocUrl(), docsDomain);
|
||||
return new ResponseEntity<>(new Json(contentStr), HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
return new ResponseEntity<>(DocResponseJson.warn("请求文档失败"), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
return new ResponseEntity<>(new Json(swaggerDoc.getJsonContent()), HttpStatus.OK);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user