ValidateApiAOP.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package com.fdkankan.openApi.aop;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.fdkankan.common.constant.ErrorCode;
  6. import com.fdkankan.common.constant.ServerCode;
  7. import com.fdkankan.openApi.constant.HttpStatus;
  8. import com.fdkankan.openApi.constant.RedisKey;
  9. import com.fdkankan.openApi.exception.ApiBusinessException;
  10. import com.fdkankan.openApi.mq.dto.CallApiDTO;
  11. import com.fdkankan.openApi.mq.sender.CallApiSender;
  12. import com.fdkankan.openApi.service.system.IUserAuthInfoService;
  13. import com.fdkankan.redis.util.RedisUtil;
  14. import com.fdkankan.web.response.ResultData;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.aspectj.lang.JoinPoint;
  17. import org.aspectj.lang.annotation.AfterReturning;
  18. import org.aspectj.lang.annotation.AfterThrowing;
  19. import org.aspectj.lang.annotation.Aspect;
  20. import org.aspectj.lang.annotation.Before;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.core.annotation.Order;
  23. import org.springframework.stereotype.Component;
  24. import org.springframework.web.context.request.RequestContextHolder;
  25. import org.springframework.web.context.request.ServletRequestAttributes;
  26. import javax.servlet.http.HttpServletRequest;
  27. @Order(999)
  28. @Component
  29. @Aspect
  30. @Slf4j
  31. public class ValidateApiAOP {
  32. @Autowired
  33. private RedisUtil redisUtil;
  34. @Autowired
  35. private CallApiSender callApiSender;
  36. @Autowired
  37. private IUserAuthInfoService userAuthService;
  38. @Autowired
  39. private LocalOverCache localOverCache;
  40. @Before("@annotation(validateApi)")
  41. public void doBefore(JoinPoint joinPoint, ValidateApi validateApi) {
  42. String method = validateApi.method();
  43. boolean counting = validateApi.counting();
  44. log.info("前置拦截鉴权,{}", method);
  45. //获取请求对象
  46. ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  47. HttpServletRequest request = servletRequestAttributes.getRequest();
  48. //请求头
  49. String authorization = request.getHeader("Authorization");
  50. if (ObjectUtil.isNull(authorization)) {
  51. throw new ApiBusinessException(ErrorCode.AUTH_FAIL);
  52. }
  53. if (!authorization.equalsIgnoreCase("admin")) {
  54. if (StrUtil.isEmpty(authorization)) {
  55. throw new ApiBusinessException(ErrorCode.AUTH_FAIL);
  56. }
  57. //数据库鉴权
  58. userAuthService.checkValidAppKey(authorization);
  59. }
  60. if (counting) {
  61. //判断是否是无限制
  62. boolean isInfinite = redisUtil.sExists(RedisKey.API_METHOD_COUNT_INFINITE, authorization);
  63. if(!isInfinite){
  64. //预减次数
  65. long decrStock = redisUtil.decr(String.format(RedisKey.API_METHOD_COUNT, authorization), 1);
  66. log.info("前置减次数后,{}", decrStock);
  67. if (decrStock < 0) {
  68. //次数用完后,redis次数会变成负一,这里需要返还一次,变为0,客户增加次数时,从0增加
  69. redisUtil.incr(String.format(RedisKey.API_METHOD_COUNT, authorization), 1);
  70. throw new ApiBusinessException(HttpStatus.COUNT_OVER, "");
  71. }
  72. }
  73. }
  74. }
  75. /**
  76. * 处理请求后执行
  77. *
  78. * @param joinPoint
  79. * @param validateApi
  80. * @param jsonResult
  81. * @return
  82. */
  83. @AfterReturning(pointcut = "@annotation(validateApi)", returning = "jsonResult")
  84. public void doAfterReturning(JoinPoint joinPoint, ValidateApi validateApi, Object jsonResult) throws NoSuchMethodException {
  85. String method = validateApi.method();
  86. boolean counting = validateApi.counting();
  87. log.info("后置拦截截鉴权计数,{},返回内容{}", method, jsonResult);
  88. //获取请求对象
  89. ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  90. HttpServletRequest request = servletRequestAttributes.getRequest();
  91. String authorization = request.getHeader("Authorization");
  92. //方法签名
  93. if (BeanUtil.toBean(jsonResult, ResultData.class).getCode() == ServerCode.SUCCESS.code()) {
  94. if (counting) {
  95. log.info("进入队列,同步数据库");
  96. callApiSender.callApi(new CallApiDTO(authorization));
  97. }
  98. } else {
  99. if (counting) {
  100. log.info("业务非正常返回,进行次数回滚+1:{}");
  101. redisUtil.incr(String.format(RedisKey.API_METHOD_COUNT, authorization), 1);
  102. }
  103. }
  104. }
  105. /**
  106. * 处理请求后执行
  107. *
  108. * @param joinPoint
  109. * @param validateApi
  110. * @param jsonResult
  111. * @return
  112. */
  113. @AfterThrowing(throwing = "ex",pointcut = "@annotation(validateApi)")
  114. public void doAfterThrowing(Throwable ex, ValidateApi validateApi) throws NoSuchMethodException {
  115. String method = validateApi.method();
  116. boolean counting = validateApi.counting();
  117. log.info("后置拦截截鉴权计数,{}", method);
  118. //获取请求对象
  119. ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  120. HttpServletRequest request = servletRequestAttributes.getRequest();
  121. String authorization = request.getHeader("Authorization");
  122. if(counting){
  123. redisUtil.incr(String.format(RedisKey.API_METHOD_COUNT, authorization), 1);
  124. }
  125. }
  126. }