Commit 3972e891 authored by 月兔回旋于空中's avatar 月兔回旋于空中

结构 >> 提交补充

parent f7760bb4
Pipeline #13327 passed with stages
in 3 minutes and 34 seconds
......@@ -21,18 +21,14 @@ repositories {
}
dependencies {
// https://mvnrepository.com/artifact/com.google.guava/guava
// https://mvnrepository.com/artifact/com.google.guava/guava
implementation group: 'com.google.guava', name: 'guava', version: '31.1-jre'
// https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter
implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
// ----- Spring Boot
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.5.7'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-freemarker
// implementation group: 'org.springframework.boot', name: 'spring-boot-starter-freemarker', version: '2.5.7'
// ----- 日志打印工具 log4j
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.0'
......
package moe.mycard.tabulator.common;
import moe.mycard.tabulator.exception.CavCore;
import moe.mycard.tabulator.exception.CavException;
import moe.mycard.tabulator.model.epi.MyCardEPI;
import moe.mycard.tabulator.model.epi.ResponseEPI;
import moe.mycard.tabulator.redis.Auth_RedisKey;
import moe.mycard.tabulator.tool.UtilEPI;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Component
public class LoginInterceptor implements HandlerInterceptor {
private final CavCore c = CavCore.getC();
public boolean isAuth = true;
// 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
@Resource private RedisTemplate<String, Long> redisTemplate;
/**
* 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
*/
public boolean preHandle(
HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
String test = request.getHeader("Authentication");
boolean auth = test != null;
if (!auth) {
throw CavException.cast(301, "无权访问");
@NotNull HttpServletRequest request,
@NotNull HttpServletResponse response,
@NotNull Object handler) {
if (isAuth) {
String token = request.getHeader("Authorization");
if (token == null) {
throw CavException.cast(301, "无权访问");
} else {
authCheck(token);
}
}
return auth;
return true;
}
private void authCheck(String token) {
String _key = Auth_RedisKey.group;
Long cacheUserId = redisTemplate.opsForValue().get(token);
if (cacheUserId == null) {
// ===== 是否在c萌服务器存在 =====
Request request =
new Request.Builder()
.url("https://sapi.moecube.com:444/accounts/authUser")
.method("GET", null)
.addHeader("Authorization", token)
.build();
try (Response response = new OkHttpClient().newBuilder().build().newCall(request).execute()) {
ResponseEPI<MyCardEPI> epi = UtilEPI.getMyCard(response);
if (epi.getCode() != 200) {
throw CavException.cast(301, "无权访问" + epi.getData().getMessage());
} else {
redisTemplate
.opsForValue()
.set(_key + token, epi.getData().encryptionId(), 1, TimeUnit.HOURS);
}
} catch (IOException e) {
throw CavException.cast(301, "无权访问,系统IO异常");
} catch (NullPointerException e) {
throw CavException.cast(301, "无权访问,请求失败");
}
// ===== 是否在c萌服务器存在 =====
} else {
redisTemplate.opsForValue().set(_key + token, cacheUserId, 1, TimeUnit.HOURS);
}
}
}
package moe.mycard.tabulator.common;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* 在springboot2.0.0之后,WebMvcConfigurerAdapter已经过时了 会使用WebMvcConfigurer或者WebMvcConfigurationSupport替代
*
* @author wyj
* @create 2019-06-01 21:48
*/
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
public class MvcConfigurer extends WebMvcConfigurationSupport {
/**
* 在springboot2.0.0之前继承WebMvcConfigurerAdapter类,重写addInterceptors方法
*
* @param registry
*/
// @Override
// public void addInterceptors(InterceptorRegistry registry) {
// /**
// * 拦截器按照顺序执行,如果不同拦截器拦截存在相同的URL,前面的拦截器会执行,后面的拦截器将不执行
// */
// registry.addInterceptor(new AuthorityInterceptor())
// .addPathPatterns("/user/**");
// super.addInterceptors(registry);
// }
/**
* 在springboot2.0.0之后实现WebMvcConfigurer接口,重写addInterceptors方法
*
* @param registry
*/
// @Override
// public void addInterceptors(InterceptorRegistry registry) {
// /**
// * 拦截器按照顺序执行,如果不同拦截器拦截存在相同的URL,前面的拦截器会执行,后面的拦截器将不执行
// */
// registry.addInterceptor(new AuthorityInterceptor())
// .addPathPatterns("/user/**");
// }
/** 由于拦截器的加载时间点在spring context之前,所以需要提前注入bean,否则拦截类内部注入注解会失效 */
@Bean
public LoginInterceptor getLoginInterceptor() {
return new LoginInterceptor();
}
/**
* 在springboot2.0.0之后继承WebMvcConfigurationSupport类,重写addInterceptors方法
*
* @param registry
* @param registry ~
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
/** 拦截器按照顺序执行,如果不同拦截器拦截存在相同的URL,前面的拦截器会执行,后面的拦截器将不执行 */
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");
registry.addInterceptor(getLoginInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
......@@ -23,9 +23,34 @@ import java.util.List;
*
* @author SPiCa
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionProcessor {
public class GlobalExceptionProcessor extends Method {
/** 全局未知异常捕获 */
@ExceptionHandler(Exception.class)
public ReturnMessage<Void> exception(Exception ex, HttpServletRequest request) {
log(true, ex, request);
return ReturnMessage.error();
}
/** 请求类型错误 */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ReturnMessage<Void> exception(
HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
log(false, ex, request);
return ReturnMessage.error("请求类型错误,该资源不支持此请求类型");
}
/** 内置异常捕获 */
@ExceptionHandler(CavException.class)
public ReturnMessage<Void> exception(CavException ex, HttpServletRequest request) {
log(true, ex, request);
return ex.result();
}
}
@Slf4j
class Method {
private static final ObjectMapper om = new ObjectMapper();
......@@ -54,28 +79,13 @@ public class GlobalExceptionProcessor {
return null;
}
/** 全局未知异常捕获 */
@ExceptionHandler(Exception.class)
public ReturnMessage<Void> exception(Exception ex, HttpServletRequest request) {
log(true, ex, request);
return ReturnMessage.error();
}
/** 请求类型错误 */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ReturnMessage<Void> exception(
HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
log(false, ex, request);
return ReturnMessage.error("请求类型错误,该资源不支持此请求类型");
}
/**
* 打印错误消息
*
* @param ex 异常信息
* @param request 请求对象
*/
private void log(boolean all, Exception ex, HttpServletRequest request) {
protected void log(boolean all, Exception ex, HttpServletRequest request) {
log.error(
"{}:************************ STR *******************************", all ? "未知异常" : "预知异常");
log.error("异常名称:【{}】", getMsg(ex));
......@@ -144,11 +154,4 @@ public class GlobalExceptionProcessor {
printCause(cause.getCause());
}
}
/** 内置异常捕获 */
@ExceptionHandler(CavException.class)
public ReturnMessage<Void> exception(CavException ex, HttpServletRequest request) {
log(false, ex, request);
return ex.result();
}
}
package moe.mycard.tabulator.model.epi;
import lombok.Data;
/** C萌平台接口响应实体 */
@Data
public class MyCardEPI {
/** 对应用户id */
private Long id;
/** 对应用户名称 */
private String username;
/** 失败的时候返回的消息 */
private String message;
/** 简易id换算,防止被外部捕获到原id */
public Long encryptionId() {
return id ^ 3399;
}
}
package moe.mycard.tabulator.model.epi;
import lombok.Data;
/** 外部接口响应报文封装体 */
@Data
public class ResponseEPI<T> {
/** 响应码 */
private Integer code;
/** 报文数据集 */
private T data;
}
package moe.mycard.tabulator.redis;
/** 权限管理key */
public class Auth_RedisKey {
/** 组名 */
public static final String group = RedisKey.global + "auth:";
}
package moe.mycard.tabulator.redis;
/** redis key */
public class RedisKey {
/** 统一组 */
public static final String global = "tabulator:";
}
package moe.mycard.tabulator.tool;
import com.alibaba.fastjson.JSON;
import moe.mycard.tabulator.model.epi.MyCardEPI;
import moe.mycard.tabulator.model.epi.ResponseEPI;
import okhttp3.Response;
import java.io.IOException;
import java.util.Objects;
/** 外部接口返回数据封装 */
public class UtilEPI {
public static ResponseEPI<MyCardEPI> getMyCard(Response response) throws IOException {
ResponseEPI<MyCardEPI> epi = new ResponseEPI<>();
epi.setCode(response.code());
epi.setData(
JSON.parseObject(Objects.requireNonNull(response.body()).string(), MyCardEPI.class));
return epi;
}
}
......@@ -19,9 +19,12 @@ spring:
url: jdbc:mysql://${IS_MYSQL_HOST:localhost}:${IS_MYSQL_PORT:3307}/${IS_MYSQL_DATABASE:ygo_table}?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: ${IS_MYSQL_USERNAME:root}
password: ${IS_MYSQL_USERPASS:spica...}
# redis:
# host: ${IS_REDIS_HOST:10.1.1.122}
# port: ${IS_REDIS_PORT:6379}
# database: ${IS_REDIS_DATABASE:1}
# # password: ${IS_REDIS_PASS:null}
# timeout: 5000
redis:
host: ${IS_REDIS_HOST:192.168.1.13}
port: ${IS_REDIS_PORT:6379}
database: ${IS_REDIS_DATABASE:1}
# password: ${IS_REDIS_PASS:null}
timeout: 5000
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment