使用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); //設置響應狀態(tài)碼 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地址的攔截,在實際開發(fā)中,我們需要做的東西更加多,考慮的情況也需要更加全面,利用更加復雜的邏輯和持久化的存儲來處理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; } }
最終結果展示:
到此這篇關于使用Spring Boot限制在一分鐘內某個IP只能訪問10次的文章就介紹到這了,更多相關springboot限制ip訪問內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Mybatis-Plus根據自定義注解實現自動加解密的示例代碼
我們把數據存到數據庫的時候,有些敏感字段是需要加密的,從數據庫查出來再進行解密,如果我們使用的是Mybatis框架,那就跟著一起探索下如何使用框架的攔截器功能實現自動加解密吧,需要的朋友可以參考下2024-06-06spring boot整合spring-kafka實現發(fā)送接收消息實例代碼
這篇文章主要給大家介紹了關于spring-boot整合spring-kafka實現發(fā)送接收消息的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來看看吧。2017-06-06Java客戶端通過HTTPS連接到Easysearch實現過程
這篇文章主要為大家介紹了Java客戶端通過HTTPS連接到Easysearch實現過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11淺談選擇、冒泡排序,二分查找法以及一些for循環(huán)的靈活運用
下面小編就為大家?guī)硪黄獪\談選擇、冒泡排序,二分查找法以及一些for循環(huán)的靈活運用。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06