|
|
@@ -1,103 +1,71 @@
|
|
|
-//package com.travel.util;
|
|
|
-//
|
|
|
-//import com.alibaba.fastjson.JSONObject;
|
|
|
-//import org.apache.commons.logging.Log;
|
|
|
-//import org.apache.commons.logging.LogFactory;
|
|
|
-//import org.springframework.stereotype.Component;
|
|
|
-//import org.springframework.web.method.HandlerMethod;
|
|
|
-//import org.springframework.web.servlet.ModelAndView;
|
|
|
-//import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
|
|
-//import javax.annotation.Resource;
|
|
|
-//import javax.servlet.http.HttpServletRequest;
|
|
|
-//import javax.servlet.http.HttpServletResponse;
|
|
|
-//
|
|
|
-///**
|
|
|
-// * @author :zzb
|
|
|
-// * @desc : 接口拦截器
|
|
|
-// */
|
|
|
-//@Component
|
|
|
-//@SuppressWarnings("all")
|
|
|
-//public class APIInterceptor extends HandlerInterceptorAdapter {
|
|
|
-//
|
|
|
-// private final Log log = LogFactory.getLog(APIInterceptor.class);
|
|
|
-//
|
|
|
-//// @Resource
|
|
|
-//// private RedisUtil.redisString redisString;
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 预处理回调方法,实现处理器的预处理(如登陆检查/判断同一对象短时间内是否重复调用接口等) 第三个参数为相应的处理器即controller
|
|
|
-// * f返回true表示流程继续,调用下一个拦截器或者处理器,返回false表示流程中断,通过response产生响应
|
|
|
-// */
|
|
|
-// @Override
|
|
|
-// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
|
|
-// throws Exception {
|
|
|
-//
|
|
|
-// //判断同一用户短时间内是否重复请求接口
|
|
|
-// log.info("========================request path==============================>"+ request.getRequestURI());
|
|
|
-// //判断请求是否属于方法的请求
|
|
|
-// if(handler instanceof HandlerMethod){
|
|
|
-// HandlerMethod hm = (HandlerMethod) handler;
|
|
|
-// //获取方法中的注解,看是否有该注解
|
|
|
-// AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
|
|
|
-// log.info("========================accessLimit==============================>"+ accessLimit);
|
|
|
-// if(accessLimit == null){
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// int seconds = accessLimit.seconds();
|
|
|
-// int maxCount = accessLimit.maxCount();
|
|
|
-// boolean login = accessLimit.needLogin();
|
|
|
-// //如果需要登录
|
|
|
-// if(login){
|
|
|
-// //获取登录的session进行判断
|
|
|
-// log.info("------------------------需要登录 ----------->"+request.getRemoteAddr());
|
|
|
-// }
|
|
|
-//
|
|
|
-// String ip=request.getRemoteAddr();
|
|
|
-// String key = request.getServletPath() + ":" + ip ;
|
|
|
-//// Integer count = (Integer) redisString.get(key);
|
|
|
-//// if (null == count || -1 == count) {
|
|
|
-//// redisString.set(key, 1,seconds);
|
|
|
-//// return true;
|
|
|
-//// }
|
|
|
-////
|
|
|
-//// if (count < maxCount) {
|
|
|
-//// count = count+1;
|
|
|
-//// redisString.set(key, count,seconds);
|
|
|
-//// return true;
|
|
|
-//// }
|
|
|
-//
|
|
|
-//// if (count >= maxCount) {
|
|
|
-//// //response 返回 json 请求过于频繁请稍后再试
|
|
|
-//// ResultBean resultBean = new ResultBean(9999,"操作过于频繁");
|
|
|
-//// response.setCharacterEncoding("UTF-8");
|
|
|
-//// response.setContentType("application/json; charset=utf-8");
|
|
|
-//// Object obj = JSONObject.toJSON(resultBean);
|
|
|
-//// response.getWriter().write(JSONObject.toJSONString(obj));
|
|
|
-//// return false;
|
|
|
-//// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// return super.preHandle(request, response, handler);
|
|
|
-// }
|
|
|
-//
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 当请求进行处理之后,也就是controller方法调用之后执行,但是他会在DispatcherServlet进行视图渲染之前被调用
|
|
|
-// * 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
|
|
|
-// */
|
|
|
-// @Override
|
|
|
-// public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
|
|
-// ModelAndView modelAndView) throws Exception {
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 方法将在整个请求结束之后,也就是DispatcheServlet进行视图渲染之后执行,这个方法的主要作用是对资源的清理工作
|
|
|
-// */
|
|
|
-// @Override
|
|
|
-// public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
|
|
-// throws Exception {
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-//}
|
|
|
+package com.travel.util;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import org.mybatis.logging.Logger;
|
|
|
+import org.mybatis.logging.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.method.HandlerMethod;
|
|
|
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 监听访问次数 防止多次访问攻击
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class SessionInterceptor extends HandlerInterceptorAdapter {
|
|
|
+
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(SessionInterceptor.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisUtil redisUtil;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
|
|
+
|
|
|
+ HandlerMethod hm = (HandlerMethod) handler;
|
|
|
+ //获取方法中的注解,看是否有该注解
|
|
|
+ AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
|
|
|
+ if(accessLimit != null){
|
|
|
+ int seconds = accessLimit.seconds();
|
|
|
+ int maxCount = accessLimit.maxCount();
|
|
|
+
|
|
|
+ //获取用户ip
|
|
|
+ String ip = request.getHeader("x-forwarded-for"); // 有可能ip是代理的
|
|
|
+ if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getHeader("Proxy-Client-IP");
|
|
|
+ }
|
|
|
+ if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getHeader("WL-Proxy-Client-IP");
|
|
|
+ }
|
|
|
+ if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getRemoteAddr();
|
|
|
+ }
|
|
|
+
|
|
|
+ //从redis中获取用户访问的次数
|
|
|
+ Integer count = Integer.parseInt(redisUtil.get(ip) == null ? "0" : redisUtil.get(ip));
|
|
|
+ if(count == 0){
|
|
|
+ //第一次访问
|
|
|
+ redisUtil.add(ip, 1, seconds, TimeUnit.SECONDS);
|
|
|
+ }else if(count < maxCount){
|
|
|
+ //加1
|
|
|
+ count = count + 1;
|
|
|
+ redisUtil.add(ip, count, seconds, TimeUnit.SECONDS);
|
|
|
+ }else{
|
|
|
+ //超出访问次数
|
|
|
+ System.out.println("访问过快ip ===> " + ip + " 且在 " + seconds + " 秒内超过最大限制 ===> " + maxCount + " 次数达到 ====> " + count);
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
+ response.setContentType("application/json; charset=utf-8");
|
|
|
+ JSONObject result = new JSONObject();
|
|
|
+ result.put("msg", "500");
|
|
|
+ result.put("errMsg", "操作太快");
|
|
|
+ Object obj = JSONObject.toJSON(result);
|
|
|
+ response.getWriter().write(JSONObject.toJSONString(obj));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return super.preHandle(request, response, handler);
|
|
|
+ }
|
|
|
+}
|