如何限制用户在某一时间段多次访问接口
来源:互联网 发布:lun网络用语是什么意思 编辑:程序博客网 时间:2024/06/05 14:54
转载自https://www.cnblogs.com/leechenxiang/p/6181449.html
要知道,如今很多平台的接口都是可以同时被门户网站,手机端,移动浏览器访问,因为接口是通用的,而为了安全起见,有些接口都会设置一个门槛,那就是限制访问次数,也就是在某一时间段内不能过多的访问,比如登录次数限制,在一些金融理财或者银行的接口上比较常见,另外一些与用户信息有关的接口都会有一个限制门槛
那么这个限制门槛怎么来做呢,其实有很多种方法,主流的做法可以用拦截器或者注解,那么今天咱们用注解来实现
首先需要定义一个注解,如下:
/** * * @Title: LimitIPRequest.java * @Package com.agood.bejavagod.component * @Description: 限制某个IP在某个时间段内请求某个方法的次数 * Copyright: Copyright (c) 2016 * Company:Nathan.Lee.Salvatore * * @author leechenxiang * @date 2016年12月14日 下午8:16:49 * @version V1.0 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documented@Order(Ordered.HIGHEST_PRECEDENCE) // 设置顺序为最高优先级public @interface LimitIPRequest { /** * * @Description: 限制某时间段内可以访问的次数,默认设置100 * @return * * @author leechenxiang * @date 2016年12月14日 下午8:22:29 */ int limitCounts() default 100; /** * * @Description: 限制访问的某一个时间段,单位为秒,默认值1分钟即可 * @return * * @author leechenxiang * @date 2016年12月14日 下午8:21:59 */ int timeSecond() default 60;}
然后再使用spring aop,拦截被你注解的那个controller的方法
@Aspect@Componentpublic class LimitIPRequestDisplay { @Autowired private JedisClient jedis; @Pointcut("execution(* com.agood.bejavagod.controller.*.*(..)) && @annotation(com.agood.bejavagod.component.LimitIPRequest)") public void before(){ } @Before("before()") public void requestLimit(JoinPoint joinPoint) throws LimitIPRequestException { try { // 获取HttpRequest ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); HttpServletResponse response = attributes.getResponse(); // 判断request不能为空 if (request == null) { throw new LimitIPRequestException("HttpServletRequest有误..."); } LimitIPRequest limit = this.getAnnotation(joinPoint); if(limit == null) { return; } String ip = request.getRemoteAddr(); String uri = request.getRequestURI().toString(); String redisKey = "limit-ip-request:" + uri + ":" + ip; // 设置在redis中的缓存,累加1 long count = jedis.incr(redisKey); // 如果该key不存在,则从0开始计算,并且当count为1的时候,设置过期时间 if (count == 1) { jedis.expire(redisKey, limit.timeSecond());// redisTemplate.expire(redisKey, limit.time(), TimeUnit.MILLISECONDS); } // 如果redis中的count大于限制的次数,则报错 if (count > limit.limitCounts()) { // logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]"); if (ShiroFilterUtils.isAjax(request)) { HttpServletResponse httpServletResponse = WebUtils.toHttp(response); httpServletResponse.sendError(ShiroFilterUtils.HTTP_STATUS_LIMIT_IP_REQUEST); } else { throw new LimitIPRequestException(); } } } catch (LimitIPRequestException e) { throw e; } catch (Exception e) { e.printStackTrace(); } } /** * * @Description: 获得注解 * @param joinPoint * @return * @throws Exception * * @author leechenxiang * @date 2016年12月14日 下午9:55:32 */ private LimitIPRequest getAnnotation(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(LimitIPRequest.class); } return null; } }
这个类使用了redis缓存作为计数器,因为好用,当然你用静态的map也行,但是考虑的分布式集群的话一般还是建议使用redis比较好。
大致的流程就是要获取redis中的调用方法次数,使用incr函数,当key不存在的时候默认为0然后累加1,当累加1大于limit设置的限制次数时,则抛出异常,这个地方需要注意,如果是ajax调用的话需要判断是否ajax,然后再返回错误信息。
阅读全文
0 0
- 如何限制用户在某一时间段多次访问接口
- 如何限制用户在某个时间段内禁止登录数据库
- 在java项目中,如何限制每个用户访问接口的次数?
- nginx limit_req限制ip在同一时间段的访问次数
- PHP结合Redis来限制用户或者IP某个时间段内访问的次数
- Nginx限制ip多次访问
- Nginx中如何限制某个IP同一时间段的访问次数
- nginx中如何限制某个IP同一时间段的访问次数
- Nginx中如何限制某个IP同一时间段的访问次数
- Nginx中如何限制某个IP同一时间段的访问次数
- Nginx中如何限制某个IP同一时间段的访问次数
- nginx中如何限制某个IP同一时间段的访问次数
- Nginx中如何限制某个IP同一时间段的访问次数
- 使用redis进行用户接口访问时间次数限制
- 如何在Linux里面限制用户空间
- MySql访问用户限制
- 接口访问次数限制
- 在linux中限制用户ftp访问权限
- 喂不饱的滴滴,也要撇开腾讯另立门户了
- kinect2.0开发环境
- 二、tomcat修改端口,字符集,内存以及增加管理员
- 共同体
- Swift中的as关键字
- 如何限制用户在某一时间段多次访问接口
- 蓝桥杯ALGO-95 2的次幂表示
- Redis系列教程Day1之Windows下的安装
- 364534543REWTERGTERTW
- 【备忘】2017年最新千峰python零基础入门视频教程下载
- Loaded plugins: fastestmirror
- 使用python做简单的中文自然语言处理
- HTML5与HTML4的区别,新增的元素有哪些?
- AngularJs(六) --指令(二)