使用Spring?Boot如何限制在一分鐘內(nèi)某個(gè)IP只能訪問10次
有些時(shí)候,為了防止我們上線的網(wǎng)站被攻擊,或者被刷取流量,我們會(huì)對(duì)某一個(gè)ip進(jìn)行限制處理,這篇文章,我們將通過Spring Boot編寫一個(gè)小案例,來實(shí)現(xiàn)在一分鐘內(nèi)同一個(gè)IP只能訪問10次,當(dāng)然具體數(shù)值,是您來決定,廢話不多說,上代碼。
首先,我們需要在Spring Boot的pom.xml文件中插入我們需要的依賴。具體的依賴部分我給出如下,也是Spring Boot常用的依賴,當(dāng)然我并未在pom文件中給出Spring Boot的使用版本,因?yàn)槲矣X得并不是每個(gè)人都使用同樣的版本,這是我使用的:
<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>
既然說到是對(duì)ip訪問的限制,那么我們可以通過攔截器來實(shí)現(xiàn)對(duì)同一個(gè)ip地址在同一段時(shí)間段內(nèi)的多次訪問進(jìn)行限制。具體代碼如下:
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; // 同一時(shí)間段內(nèi)允許的最大請求數(shù) private static final long TIME_PERIOD = 60 * 1000; // 時(shí)間段,單位為毫秒 在一分鐘內(nèi)限制ip訪問次數(shù)為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 地址是否已經(jīng)達(dá)到最大請求數(shù) if (requestCounts.containsKey(ipAddress) && requestCounts.get(ipAddress) >= MAX_REQUESTS) { response.setStatus(429); //設(shè)置響應(yīng)狀態(tài)碼 response.getWriter().write("Too many requests from this IP address"); return false; } // 更新 IP 地址的請求數(shù) requestCounts.put(ipAddress, requestCounts.getOrDefault(ipAddress, 0) + 1); // 在指定時(shí)間后清除 IP 地址的請求數(shù) new Timer().schedule( new TimerTask() { @Override public void run() { requestCounts.remove(ipAddress); } }, TIME_PERIOD ); return true; } }
在這段代碼中,我們使用了一個(gè)Map來存儲(chǔ)每個(gè)IP地址的請求數(shù),在preHandle方法中,我們首先檢查IP地址的請求數(shù)是否已經(jīng)達(dá)到最大請求數(shù),如果是,則返回一個(gè)429當(dāng)前IP地址的請求次數(shù)太多,一分鐘只能請求10次,當(dāng)然這決定權(quán)在你,然后我們更新IP地址的請求數(shù),并在指定的時(shí)間段后清除該IP地址的請求數(shù)。
接下來,我們需要在配置類中注冊攔截器,我采用的事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); } }
在本段代碼中,我們通過構(gòu)造函數(shù)注入 RateLimitInterceptor
,然后在 addInterceptors
方法中將攔截器添加到攔截器注冊表中。
現(xiàn)在,當(dāng)同一 IP 地址在同一時(shí)間段內(nèi)的請求數(shù)達(dá)到最大限制時(shí),它將收到一個(gè) 429的響應(yīng)。你可以根據(jù)自己的需求調(diào)整最大請求數(shù)和時(shí)間段。
需要注意的是,這個(gè)小案例只是簡答實(shí)現(xiàn)了對(duì)IP地址的攔截,在實(shí)際開發(fā)中,我們需要做的東西更加多,考慮的情況也需要更加全面,利用更加復(fù)雜的邏輯和持久化的存儲(chǔ)來處理IP地址的請求限制。
接下來,我們通過Controller類來測試我們的寫的案例是否實(shí)現(xiàn)這個(gè)功能:
@RestController @RequestMapping("user/") public class UserController { @RequestMapping("demo") public String test(){ return "測試"; } @RequestMapping("userDemo") public User userDemo(User user){ return user; } }
User其實(shí)可寫可不寫,但是便于重復(fù)利用,我這里給出User的實(shí)體類吧:
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; } }
最終結(jié)果展示:
到此這篇關(guān)于使用Spring Boot限制在一分鐘內(nèi)某個(gè)IP只能訪問10次的文章就介紹到這了,更多相關(guān)springboot限制ip訪問內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-Plus根據(jù)自定義注解實(shí)現(xiàn)自動(dòng)加解密的示例代碼
我們把數(shù)據(jù)存到數(shù)據(jù)庫的時(shí)候,有些敏感字段是需要加密的,從數(shù)據(jù)庫查出來再進(jìn)行解密,如果我們使用的是Mybatis框架,那就跟著一起探索下如何使用框架的攔截器功能實(shí)現(xiàn)自動(dòng)加解密吧,需要的朋友可以參考下2024-06-06spring boot整合spring-kafka實(shí)現(xiàn)發(fā)送接收消息實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于spring-boot整合spring-kafka實(shí)現(xiàn)發(fā)送接收消息的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來看看吧。2017-06-06Java解析http協(xié)議字符串的方法實(shí)現(xiàn)
本文主要介紹了Java解析http協(xié)議字符串的方法實(shí)現(xiàn),我們探討了如何使用Java解析HTTP協(xié)議字符串,并將其封裝成了一個(gè)HttpRequest類,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09java實(shí)現(xiàn)統(tǒng)一異常處理的示例
一個(gè)全局異常處理類需要處理三類異常1.業(yè)務(wù)類異常,2.運(yùn)行時(shí)異常 ,3.Error,本文給大家介紹java實(shí)現(xiàn)統(tǒng)一異常處理的示例,感興趣的朋友一起看看吧2021-06-06Java中使用正則表達(dá)式獲取網(wǎng)頁中所有圖片的路徑
這篇文章主要介紹了Java中使用正則表達(dá)式獲取網(wǎng)頁中所有圖片的路徑,本文直接給出實(shí)例代碼,需要的朋友可以參考下2015-06-06Maven中exec插件執(zhí)行Java程序的實(shí)現(xiàn)
在Maven項(xiàng)目中,可以使用Maven的插件來執(zhí)行Java程序,本文主要介紹了Maven中exec插件執(zhí)行Java程序的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12Java客戶端通過HTTPS連接到Easysearch實(shí)現(xiàn)過程
這篇文章主要為大家介紹了Java客戶端通過HTTPS連接到Easysearch實(shí)現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11淺談選擇、冒泡排序,二分查找法以及一些for循環(huán)的靈活運(yùn)用
下面小編就為大家?guī)硪黄獪\談選擇、冒泡排序,二分查找法以及一些for循環(huán)的靈活運(yùn)用。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06