您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Spring Boot如何防止接口恶意刷新和暴力请求

2024/3/8 11:55:01发布18次查看
首先创建一个自定义的拦截器类,也是最核心的代码;
/** * @package: com.technicalinterest.group.interceptor * @classname: ipurllimitinterceptor * @description: ip+url重复请求现在拦截器 * @author: shuyu.wang * @date: 2019-10-12 12:34 * @since: 0.1 **/@slf4jpublic class ipurllimitinterceptor implements handlerinterceptor { private redisutil getredisutil() { return springcontextutil.getbean(redisutil.class); } private static final string lock_ip_url_key="lock_ip_"; private static final string ip_url_req_time="ip_url_times_"; private static final long limit_times=5; private static final int ip_lock_time=60; @override public boolean prehandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o) throws exception { log.info("request请求地址uri={},ip={}", httpservletrequest.getrequesturi(), ipadrressutil.getipadrress(httpservletrequest)); if (ipislock(ipadrressutil.getipadrress(httpservletrequest))){ log.info("ip访问被禁止={}",ipadrressutil.getipadrress(httpservletrequest)); apiresult result = new apiresult(resultenum.lock_ip); returnjson(httpservletresponse, json.tojsonstring(result)); return false; } if(!addrequesttime(ipadrressutil.getipadrress(httpservletrequest),httpservletrequest.getrequesturi())){ apiresult result = new apiresult(resultenum.lock_ip); returnjson(httpservletresponse, json.tojsonstring(result)); return false; } return true; } @override public void posthandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview) throws exception { } @override public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception { } /** * @description: 判断ip是否被禁用 * @author: shuyu.wang * @date: 2019-10-12 13:08 * @param ip * @return java.lang.boolean */ private boolean ipislock(string ip){ redisutil redisutil=getredisutil(); if(redisutil.haskey(lock_ip_url_key+ip)){ return true; } return false; } /** * @description: 记录请求次数 * @author: shuyu.wang * @date: 2019-10-12 17:18 * @param ip * @param uri * @return java.lang.boolean */ private boolean addrequesttime(string ip,string uri){ string key=ip_url_req_time+ip+uri; redisutil redisutil=getredisutil(); if (redisutil.haskey(key)){ long time=redisutil.incr(key,(long)1); if (time>=limit_times){ redisutil.getlock(lock_ip_url_key+ip,ip,ip_lock_time); return false; } }else { redisutil.getlock(key,(long)1,1); } return true; } private void returnjson(httpservletresponse response, string json) throws exception { printwriter writer = null; response.setcharacterencoding("utf-8"); response.setcontenttype("text/json; charset=utf-8"); try { writer = response.getwriter(); writer.print(json); } catch (ioexception e) { log.error("logininterceptor response error ---> {}", e.getmessage(), e); } finally { if (writer != null) { writer.close(); } } } }
代码中redis的使用的是分布式锁的形式,这样可以最大程度保证线程安全和功能的实现效果。代码中设置的是1s内同一个接口通过同一个ip访问5次,就将该ip禁用1个小时,根据自己项目需求可以自己适当修改,实现自己想要的功能;
redis分布式锁的关键代码:
/** * @package: com.shuyu.blog.util * @classname: redisutil * @description: * @author: shuyu.wang * @date: 2019-07-14 14:42 * @since: 0.1 **/@component@slf4jpublic class redisutil { private static final long success = 1l; @autowired private redistemplate<string, object> redistemplate; // =============================common============================ /** * 获取锁 * @param lockkey * @param value * @param expiretime:单位-秒 * @return */ public boolean getlock(string lockkey, object value, int expiretime) { try { log.info("添加分布式锁key={},expiretime={}",lockkey,expiretime); string script = "if redis.call('setnx',keys[1],argv[1]) then if redis.call('get',keys[1])==argv[1] then return redis.call('expire',keys[1],argv[2]) else return 0 end end"; redisscript<string> redisscript = new defaultredisscript<>(script, string.class); object result = redistemplate.execute(redisscript, collections.singletonlist(lockkey), value, expiretime); if (success.equals(result)) { return true; } } catch (exception e) { e.printstacktrace(); } return false; } /** * 释放锁 * @param lockkey * @param value * @return */ public boolean releaselock(string lockkey, string value) { string script = "if redis.call('get', keys[1]) == argv[1] then return redis.call('del', keys[1]) else return 0 end"; redisscript<string> redisscript = new defaultredisscript<>(script, string.class); object result = redistemplate.execute(redisscript, collections.singletonlist(lockkey), value); if (success.equals(result)) { return true; } return false; } }
最后将上面自定义的拦截器通过registry.addinterceptor添加一下,就生效了;
@configuration@slf4jpublic class mywebappconfig extends webmvcconfigureradapter { @bean ipurllimitinterceptor getipurllimitinterceptor(){ return new ipurllimitinterceptor(); } @override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(getipurllimitinterceptor()).addpathpatterns("/**"); super.addinterceptors(registry); }}
以上就是spring boot如何防止接口恶意刷新和暴力请求的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product