spring boot中的拦截器限制用户访问接口次数
2018-01-06 19:00
806 查看
1、自定义一个拦截器集成HandlerInterceptorAdapter里面的preHandle方法
@Service public class AccessInterceptor extends HandlerInterceptorAdapter{ @Autowired RedisService redisService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(handler instanceof HandlerMethod) { User user = getUser(request, response); UserContext.setUser(user); HandlerMethod hm = (HandlerMethod)handler; AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);//请求的方法是否带有accesslimit注解 if(accessLimit == null) { return true; } //如果有判断每请求一次缓存中当前用户key的count+1.直到最大限制禁止访问此接口 int seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); boolean needLogin = accessLimit.needLogin(); String key = request.getRequestURI(); if(needLogin) { if(user == null) { render(response, CodeMsg.SESSION_ERROR); return false; } key += "_" + user.getId(); }else { //do nothing } AccessKey ak = AccessKey.withExpire(seconds); Integer count = redisService.get(ak, key, Integer.class); if(count == null) { redisService.set(ak, key, 1); }else if(count < maxCount) { redisService.incr(ak, key); }else { render(response, CodeMsg.ACCESS_LIMIT_REACHED); return false; } } return true; } //返回前台 private void render(HttpServletResponse response, CodeMsg cm)throws Exception { response.setContentType("application/json;charset=UTF-8"); OutputStream out = response.getOutputStream(); String str = JSON.toJSONString(Result.error(cm)); out.write(str.getBytes("UTF-8")); out.flush(); out.close(); } //用户带来的redis key值可能在cookie中或者参数中 private User getUser(HttpServletRequest request, HttpServletResponse response) { String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN); String cookieToken = getCookieValue(request, UserService.COOKI_NAME_TOKEN); if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) { return null; } String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken; return userService.getByToken(response, token); } private String getCookieValue(HttpServletRequest request, String cookiName) { Cookie[] cookies = request.getCookies(); if(cookies == null || cookies.length <= 0){ return null; } for(Cookie cookie : cookies) { if(cookie.getName().equals(cookiName)) { return cookie.getValue(); } } return null; } }
/** * 在mvc配置拦截器 * @param registry */ @Configuration //等价于<mvc:annotation-driven/> @EnableWebMvc public class MVCConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware { @Override public void addInterceptors(InterceptorRegistry registry) { String interceptPath = ""; //注册拦截器 InterceptorRegistration loginIR = registry.addInterceptor(new AccessInterceptor ()); //配置拦截路径 loginIR.addPathPatterns(interceptPath); //注册其他拦截器 InterceptorRegistration permissionIR = registry.addInterceptor(new UserPermissionInterceptor()); //配置拦截路径 permissionIR.addPathPatterns(interceptPath); //配置不拦截路径 permissionIR.excludePathPatterns(""); }
//将数据存在当前线程中,当前线程安全 public class UserContext { private static ThreadLocal<User> userHolder = new ThreadLocal<User>(); public static void setUser(User user) { userHolder.set(user); } public static User getUser() { return userHolder.get(); } }
//自定义限制注解,加载controller url 上 @Retention(RUNTIME) @Target(METHOD) public @interface AccessLimit { int seconds(); int maxCount(); boolean needLogin() default true; }
相关文章推荐
- 在java项目中,如何限制每个用户访问接口的次数?
- SpringBoot中自定义注解实现控制器访问次数限制实例
- 使用redis进行用户接口访问时间次数限制
- springboot和redis控制单位时间内同个ip访问同个接口的次数
- 拦截器限制用户访问次数和验证用户登录代码
- cxf+spring开发(三)--- 限制固定Ip地址对接口的访问次数
- SpringBoot中自定义注解实现控制器访问次数限制
- 限制每个用户访问接口的次数(Java)
- SpringBoot 实现控制器 IP 访问次数限制
- SpringBoot 实现控制器 IP 访问次数限制
- 如何限制用户在某一时间段多次访问接口
- SpringBoot中实现拦截器级别的URl访问过快拦截,并利用JPA实现IP黑名单的功能。
- SpringBoot之拦截器对数据库的访问
- 【SpringBoot】拦截器使用@Autowired注入接口为null解决方法
- 如何限制用户在某一时间段多次访问接口
- spring boot 中访问 REST 接口
- [置顶] 【三】Springboot+Redis实现密码次数限制
- STS创建Spring Boot项目实战(Rest接口、数据库、用户认证、分布式Token JWT、Redis操作、日志和统一异常处理)
- Django-Rest frameworw用户访问次数/频率限制
- SpringBoot启动后为何无法正常访问接口