网站的防攻击逻辑代码

网站验证防攻击,当ip验证次数大于10,或者电话验证次数大于5.就添加黑名单。并24小时后恢复

首先,我们创建一个对象,存储ip的验证次数和验证时间

@AllArgsConstructor
@NoArgsConstructor
public class CountAndTime {
    Integer Count;
    LocalDateTime time;

    public Integer getCount() {
        return Count;
    }

    public CountAndTime setCount(Integer count) {
        Count = count;
        return this;
    }

    public LocalDateTime getTime() {
        return time;
    }

    public void setTime(LocalDateTime time) {
        this.time = time;
    }
}

通过创建一个map类型的数据合适,key存储的是ip地址或者电话。value存放以上次数和时间对象

Map<String,CountAndTime> ipCount = new HashMap<>();
Map<String,CountAndTime> telCount = new HashMap<>();

以下为ip和电话的限制次数,并达到24小时后恢复限制的方法,限制返回flase。通过返回true

 /**
     * ip限制次数
     * @param request
     * @return
     * @throws UnknownHostException
     */
    public Boolean IpRestrict (HttpServletRequest request) {
        Map<String,Object> res = new HashMap<>();
        String ip = HttpUtil.getIp(request);        //获取访问ip
        if (ipCount.get(ip)==null){
            ipCount.put(ip, new CountAndTime(1, LocalDateTime.now()));     //如果ip未验证,则添加到map,次数为1
        }else{
            ipCount.put(ip,ipCount.get(ip).setCount(ipCount.get(ip).getCount()+1));      //如果已经验证,访问次数+1
            Duration between = Duration.between(ipCount.get(ip).getTime(), LocalDateTime.now());        //比较两个时间的分钟差
            if (between.toMinutes()>=1440){     //如果大于1440分钟,24小时。则重新更新当前ip时间为当前,次数为1
                ipCount.put(ip, new CountAndTime(1, LocalDateTime.now()));
            }
        }
        return ipCount.get(ip).getCount() <= 10;           //当验证次数大于10,则限制该ip,返回false
    }

    /**
     * 电话限制次数
     * @return
     * @throws UnknownHostException
     */
    public Boolean TelRestrict (String tel) {

        Map<String,Object> res = new HashMap<>();
        if (telCount.get(tel)==null){
            telCount.put(tel, new CountAndTime(1, LocalDateTime.now()));     //如果ip未验证,则添加到map,次数为1
        }else{
            telCount.put(tel,telCount.get(tel).setCount(telCount.get(tel).getCount()+1));      //如果已经验证,访问次数+1
            Duration between = Duration.between(telCount.get(tel).getTime(), LocalDateTime.now());    //比较两个时间的分钟差
            if (between.toMinutes()>=1440){           //如果大于1440分钟,24小时。则重新更新当前ip时间为当前,次数为1
                telCount.put(tel, new CountAndTime(1, LocalDateTime.now()));
            }
        }
        return telCount.get(tel).getCount() <= 5;           //当验证次数大于10,则限制该ip,返回false
    }

网站页面请求防攻击逻辑代码(带注释)

需要用到httpUtil工具类,请前往我的另一篇文章获取。传送门

public class SafetyFilter implements HandlerInterceptor {
    @Value("${SafetyFilter.reCount}")
    String reCountStr="10";
    @Value("${SafetyFilter.temporal}")
    String temporalStr="3";
    @Value("${SafetyFilter.lockTime}")
    String lockTimeStr="15";

    Integer lockTime=Integer.valueOf(lockTimeStr);
    Integer reCount=Integer.valueOf(reCountStr);      //请求次数
    Integer temporal=Integer.valueOf(temporalStr);     //时间频率

    Map<String,RequestIp> re = new HashMap<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        PrintWriter out = null;//返回给页面显示
        //取用户的真实IP
        String ip = HttpUtil.getIp(request);
        RequestIp requestIp = re.get(ip);
        //第一次请求
        if(null == requestIp){              //如果对象为空,则新建对象,放入map中
            RequestIp reIp = new RequestIp();
            reIp.setCreateTime(System.currentTimeMillis());
            reIp.setReCount(1);
            re.put(ip,reIp);
        }else{                                      //如果不是第一次请求
            Long createTime = requestIp.getCreateTime();        //获取第一次请求的创建时间
            if (re.get(ip).getReCount()==0){            //当次数等于零的时候,就知道是锁住了
                if ((System.currentTimeMillis()-re.get(ip).getCreateTime())/1000>lockTime*60){      //如果锁定的时间与现在的时间相差15分钟,就解锁
                    re.put(ip, re.get(ip).setReCount(1));
                }
                return false;
            }
            if(((System.currentTimeMillis() - createTime)/1000) > temporal){        //如果请求的频率大于3s,直接放行
                System.out.println("通过请求!"+((System.currentTimeMillis() - createTime)/1000));
                //当前时间离上一次请求时间大于3秒,可以直接通过,保存这次的请求
                RequestIp reIp = new RequestIp();
                reIp.setCreateTime(System.currentTimeMillis());
                reIp.setReCount(1);         //并且请求次数重新设置为1
                re.put(ip, reIp);
                return true;
            }else{
                //小于3秒,并且3秒之内请求了10次,返回提示
                if(requestIp.getReCount() > reCount){
                    request.getSession().setAttribute("reqcode",503);
                    request.getSession().setAttribute("reqmsg","请求太快,请稍后再试!");
                    re.put(ip, new RequestIp(System.currentTimeMillis(),0));        //锁定ip
                    return false;
                }else{
                    //小于3秒,但请求数小于10次,给对象添加
                    requestIp.setCreateTime(System.currentTimeMillis());
                    requestIp.setReCount(requestIp.getReCount()+1);
                    re.put(ip,requestIp);
                    return true;
                }
            }
            }
        return true;
    }
    // 在业务处理器处理请求完成之后,生成视图之前执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception{
    }
    // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception{
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

languageStudents

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值