使用Spring Boot限制在一分钟内某个IP只能访问10次

有些时候,为了防止我们上线的网站被攻击,或者被刷取流量,我们会对某一个ip进行限制处理,这篇文章,我们将通过Spring Boot编写一个小案例,来实现在一分钟内同一个IP只能访问10次,当然具体数值,是您来决定,废话不多说,上代码。

首先,我们需要在Spring Boot的pom.xml文件中插入我们需要的依赖。具体的依赖部分我给出如下,也是Spring Boot常用的依赖,当然我并未在pom文件中给出Spring Boot的使用版本,因为我觉得并不是每个人都使用同样的版本,这是我使用的:
在这里插入图片描述

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

既然说到是对ip访问的限制,那么我们可以通过拦截器来实现对同一个ip地址在同一段时间段内的多次访问进行限制。具体代码如下:

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Miaow.Y.Hu
 * @date 2023年10月24日 19:01
 * @description
 */


@Component
public class RateLimitInterceptor implements HandlerInterceptor {

    private static final int MAX_REQUESTS = 10; // 同一时间段内允许的最大请求数
    private static final long TIME_PERIOD = 60 * 1000; // 时间段,单位为毫秒 在一分钟内限制ip访问次数为10次

    private Map<String, Integer> requestCounts = new HashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ipAddress = request.getRemoteAddr();
        System.out.println(ipAddress);
        // 检查 IP 地址是否已经达到最大请求数
        if (requestCounts.containsKey(ipAddress) && requestCounts.get(ipAddress) >= MAX_REQUESTS) {
            response.setStatus(429); //设置响应状态码
            response.getWriter().write("Too many requests from this IP address");
            return false;
        }

        // 更新 IP 地址的请求数
        requestCounts.put(ipAddress, requestCounts.getOrDefault(ipAddress, 0) + 1);

        // 在指定时间后清除 IP 地址的请求数
        new Timer().schedule(
                new TimerTask() {
                    @Override
                    public void run() {
                        requestCounts.remove(ipAddress);
                    }
                },
                TIME_PERIOD
        );
        return true;
    }
}

在这段代码中,我们使用了一个Map来存储每个IP地址的请求数,在preHandle方法中,我们首先检查IP地址的请求数是否已经达到最大请求数,如果是,则返回一个429当前IP地址的请求次数太多,一分钟只能请求10次,当然这决定权在你,然后我们更新IP地址的请求数,并在指定的时间段后清除该IP地址的请求数。

接下来,我们需要在配置类中注册拦截器,我采用的事WebMvcConfig:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final RateLimitInterceptor rateLimitInterceptor;

    @Autowired
    public WebMvcConfig(RateLimitInterceptor rateLimitInterceptor) {
        this.rateLimitInterceptor = rateLimitInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(rateLimitInterceptor);
    }
}

在本段代码中,我们通过构造函数注入 RateLimitInterceptor,然后在 addInterceptors 方法中将拦截器添加到拦截器注册表中。

现在,当同一 IP 地址在同一时间段内的请求数达到最大限制时,它将收到一个 429的响应。你可以根据自己的需求调整最大请求数和时间段。

需要注意的是,这个小案例只是简答实现了对IP地址的拦截,在实际开发中,我们需要做的东西更加多,考虑的情况也需要更加全面,利用更加复杂的逻辑和持久化的存储来处理IP地址的请求限制。

接下来,我们通过Controller类来测试我们的写的案例是否实现这个功能:

@RestController
@RequestMapping("user/")
public class UserController {

    @RequestMapping("demo")
    public String test(){
        return "测试";
    }

    @RequestMapping("userDemo")
    public User userDemo(User user){
        return  user;
    }
}

User其实可写可不写,但是便于重复利用,我这里给出User的实体类吧:

public class User {
    private Long id;
    private String name;
    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(age, user.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }

    public User() {
    }

    public User(Long id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

最终结果展示:
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Boot中,我们可以使用拦截器(Interceptor)来实现游客点赞根据IP进行限制。 首先,我们需要定义一个拦截器来拦截用户点赞请求,判断该IP地址当天是否已经点过赞。如果已经点过赞,则返回错误提示信息;否则,允许用户进行点赞。 ```java public class LikeInterceptor implements HandlerInterceptor { private static final Map<String, Set<String>> LIKE_RECORDS = new HashMap<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ipAddress = request.getRemoteAddr(); String articleId = request.getParameter("articleId"); // 判断该IP地址当天是否已经点过赞 Set<String> likeRecords = LIKE_RECORDS.getOrDefault(ipAddress, new HashSet<>()); if (likeRecords.contains(articleId)) { response.getWriter().write("您已经点过赞了!"); return false; } // 如果没有点过赞,则记录该IP地址和文章ID,允许用户进行点赞 likeRecords.add(articleId); LIKE_RECORDS.put(ipAddress, likeRecords); return true; } } ``` 上面的代码中,我们定义了一个`LikeInterceptor`拦截器,其中`LIKE_RECORDS`用于记录每个IP地址当天点赞的文章ID。在`preHandle`方法中,我们首先获取用户的IP地址和文章ID,然后判断该IP地址当天是否已经点过赞。如果已经点过赞,则返回错误提示信息;否则,记录该IP地址和文章ID,允许用户进行点赞。 接下来,我们需要将拦截器添加到Spring Boot应用中。在我们的配置类中,使用`addInterceptor`方法将`LikeInterceptor`拦截器添加到Spring Boot应用中。 ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LikeInterceptor()).addPathPatterns("/like"); } } ``` 上面的代码中,我们将`LikeInterceptor`拦截器添加到路径为`/like`的请求中。这样,当用户发送点赞请求时,拦截器会拦截请求并进行IP地址限制。 最后,我们需要在前端页面中发送点赞请求,将文章ID作为参数传递给后端。例如,我们可以在前端页面中使用jQuery发送点赞请求: ```javascript $.ajax({ url: "/like", type: "POST", data: { articleId: 123 }, success: function (data) { alert(data); } }); ``` 上面的代码中,我们使用POST方式发送点赞请求,将文章ID作为参数传递给后端。如果后端返回错误提示信息,则弹出提示框显示错误信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Miaow.Y.Hu

赏一口饭吃吧,大大们

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

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

打赏作者

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

抵扣说明:

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

余额充值