欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實(shí)現(xiàn)基于URL和IP的訪問(wèn)頻率限制

 更新時(shí)間:2025年01月08日 09:02:37   作者:孤蓬&聽(tīng)雨  
在現(xiàn)代?Web?應(yīng)用中,接口被惡意刷新或暴力請(qǐng)求是一種常見(jiàn)的攻擊手段,為了保護(hù)系統(tǒng)資源,需要對(duì)接口的訪問(wèn)頻率進(jìn)行限制,下面我們就來(lái)看看如何使用?Spring?Boot?實(shí)現(xiàn)基于?URL?和?IP?的訪問(wèn)頻率限制吧

1. 引言

在現(xiàn)代 Web 應(yīng)用中,接口被惡意刷新或暴力請(qǐng)求是一種常見(jiàn)的攻擊手段。為了保護(hù)系統(tǒng)資源,防止服務(wù)器過(guò)載或服務(wù)不可用,需要對(duì)接口的訪問(wèn)頻率進(jìn)行限制。本文將介紹如何使用 Spring Boot 實(shí)現(xiàn)基于 URL 和 IP 的訪問(wèn)頻率限制,具體步驟包括:

使用攔截器攔截請(qǐng)求:在每個(gè)請(qǐng)求到達(dá)控制器之前進(jìn)行攔截。

使用 Redis 存儲(chǔ)訪問(wèn)記錄:利用 Redis 的高性能特性來(lái)存儲(chǔ)每個(gè) IP 對(duì)每個(gè) URL 的訪問(wèn)次數(shù)。

檢測(cè)訪問(wèn)頻率:判斷 IP 在一定時(shí)間內(nèi)對(duì)特定 URL 的訪問(wèn)次數(shù)是否超過(guò)限制。

禁用惡意 IP:如果超過(guò)限制,則將 IP 列入黑名單,禁止其后續(xù)訪問(wèn)。

2. 項(xiàng)目依賴

首先,在 pom.xml 中添加必要的依賴,包括 Spring Boot Web、Spring Boot Starter Data Redis 和 Lombok(用于簡(jiǎn)化代碼)。

<!-- Spring Boot Starter Data Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>3.4.1</version>
</dependency>

<!-- Lombok (可選,用于簡(jiǎn)化代碼) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

3. 配置 Redis

在 application.properties 中配置 Redis 連接信息:

server.port=8080
# Redis 配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=0
# 可選:設(shè)置密碼
# spring.redis.password=yourpassword

或在 application.yml 中配置Redis連接信息:

server:
  port: 8080

spring:
  application:
    name: urlInterceptorDemo

  data:
    # redis 配置
    redis:
      # 地址
      host: 127.0.0.1
      # 端口,默認(rèn)為6379
      port: 6379
      # 數(shù)據(jù)庫(kù)索引
      database: 0
      # 密碼
      password: "123456"
      # 連接超時(shí)時(shí)間
      timeout: 10s

4. 創(chuàng)建攔截器

創(chuàng)建一個(gè)攔截器 RateLimitInterceptor,用于攔截每個(gè)請(qǐng)求并執(zhí)行訪問(wèn)頻率限制邏輯。

package com.yyqq.urlinterceptordemo.Interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.concurrent.TimeUnit;

@Component
public class RateLimitInterceptor implements HandlerInterceptor {

    @Autowired
    public RedisTemplate redisTemplate;

    // 訪問(wèn)頻率限制:每個(gè) IP 每個(gè) URL 最多訪問(wèn) 100 次 / 分鐘
    private static final int MAX_REQUESTS = 10;
    private static final int TIME_WINDOW = 60; // 秒

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip = getClientIP(request);
        String url = request.getRequestURI();

        String key = "rate_limit:" + url + ":" + ip;
        long count = redisTemplate.opsForValue().increment(key, 1);
        if (count == 1) {
            // 設(shè)置鍵的過(guò)期時(shí)間為 TIME_WINDOW 秒
            redisTemplate.expire(key, TIME_WINDOW, TimeUnit.SECONDS);
        }

        if (count > MAX_REQUESTS) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("請(qǐng)求過(guò)于頻繁,請(qǐng)稍后再試。");
            return false;
        }

        return true;
    }

    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

代碼說(shuō)明

RedisTemplate:用于與 Redis 進(jìn)行交互。

MAX_REQUESTS 和 TIME_WINDOW:定義每個(gè) IP 在每個(gè) URL 上的最大訪問(wèn)次數(shù)和時(shí)間窗口(60 秒)。

preHandle 方法:

獲取客戶端 IP 和請(qǐng)求的 URL。

構(gòu)建 Redis 鍵,例如 rate_limit:/api/data:192.168.1.1。

使用 increment 方法對(duì)鍵進(jìn)行遞增,并設(shè)置過(guò)期時(shí)間。

如果訪問(wèn)次數(shù)超過(guò) MAX_REQUESTS,則返回 403 狀態(tài)碼,并返回錯(cuò)誤信息。

getClientIP 方法:獲取客戶端的真實(shí) IP,處理代理和負(fù)載均衡的情況。

5. 注冊(cè)攔截器

創(chuàng)建一個(gè)配置類 WebConfig,將攔截器注冊(cè)到 Spring MVC 中。

package com.yyqq.urlinterceptordemo.config;


import com.yyqq.urlinterceptordemo.Interceptor.RateLimitInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private RateLimitInterceptor rateLimitInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(rateLimitInterceptor)
                .addPathPatterns("/**") // 攔截所有路徑
                .excludePathPatterns("/error"); // 排除錯(cuò)誤路徑
    }
}

代碼說(shuō)明

  • addInterceptors 方法:將自定義的攔截器添加到攔截器鏈中,并指定攔截的路徑模式。
  • addPathPatterns("/")**:攔截所有路徑。
  • excludePathPatterns(“/error”):排除錯(cuò)誤路徑,避免攔截器影響錯(cuò)誤處理。

6. 創(chuàng)建控制器

創(chuàng)建一個(gè)簡(jiǎn)單的控制器 DemoController,包含一個(gè)示例接口用于測(cè)試。

package com.yyqq.urlinterceptordemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class DemoController {

    @GetMapping("/getData")
    public String getData() {
        return "這是數(shù)據(jù)接口,現(xiàn)在訪問(wèn)正常!";
    }
}

8. 測(cè)試

啟動(dòng) Spring Boot 應(yīng)用后,可以進(jìn)行以下測(cè)試:

1.正常訪問(wèn):

訪問(wèn) http://localhost:8080/test/getData,應(yīng)返回 “這是數(shù)據(jù)接口,現(xiàn)在訪問(wèn)正常!”。

多次快速刷新,訪問(wèn)次數(shù)達(dá)到 10 次后,應(yīng)返回 “請(qǐng)求過(guò)于頻繁,請(qǐng)稍后再試。”,并返回 403 狀態(tài)碼。

2.禁用 IP:

在達(dá)到限制后,等待一段時(shí)間(60 秒),再次訪問(wèn)應(yīng)恢復(fù)正常。

9. 總結(jié)

通過(guò)結(jié)合使用 Spring Boot 攔截器和 Redis,本文實(shí)現(xiàn)了一種基于 URL 和 IP 的訪問(wèn)頻率限制機(jī)制。這種機(jī)制能夠有效地防止接口被惡意刷新和暴力請(qǐng)求,保護(hù)系統(tǒng)資源,提高應(yīng)用的安全性和穩(wěn)定性。在實(shí)際應(yīng)用中,可以根據(jù)具體需求調(diào)整訪問(wèn)頻率限制的參數(shù),如最大訪問(wèn)次數(shù)和時(shí)間窗口。此外,還可以結(jié)合其他安全措施,如 IP 黑名單、驗(yàn)證碼等,進(jìn)一步增強(qiáng)系統(tǒng)的防護(hù)能力。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)基于URL和IP的訪問(wèn)頻率限制的文章就介紹到這了,更多相關(guān)SpringBoot訪問(wèn)頻率限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Springboot+React項(xiàng)目跨域訪問(wèn)問(wèn)題

    詳解Springboot+React項(xiàng)目跨域訪問(wèn)問(wèn)題

    這篇文章主要介紹了詳解Springboot+React項(xiàng)目跨域訪問(wèn)問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Future與FutureTask接口實(shí)現(xiàn)示例詳解

    Future與FutureTask接口實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了Future與FutureTask接口實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Apache?Hudi異步Clustering部署操作的掌握

    Apache?Hudi異步Clustering部署操作的掌握

    這篇文章主要介紹了Apache?Hudi異步Clustering部署操作的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-03-03
  • Json字符串轉(zhuǎn)Java對(duì)象和List代碼實(shí)例

    Json字符串轉(zhuǎn)Java對(duì)象和List代碼實(shí)例

    這篇文章主要介紹了Json字符串轉(zhuǎn)Java對(duì)象和List代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java虛擬機(jī)棧jvm棧的作用

    Java虛擬機(jī)棧jvm棧的作用

    本文主要介紹了Java虛擬機(jī)棧jvm棧的作用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java?Spring的核心與設(shè)計(jì)思想你知道嗎

    Java?Spring的核心與設(shè)計(jì)思想你知道嗎

    這篇文章主要為大家詳細(xì)介紹了Java?Spring的核心與設(shè)計(jì)思想,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • 詳解Java事件編程的使用

    詳解Java事件編程的使用

    Java事件在很多地方都可以使用,合理的使用事件編程,相比常規(guī)邏輯的編程,這可達(dá)到主次分明,讓程序吞吐量即處理能力更強(qiáng),改動(dòng)更少,下面我們舉一個(gè)例子說(shuō)明如何使用Java使用,需要的朋友可以參考下
    2021-06-06
  • SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空

    SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空

    SpringBoot整合Mybatis-plus使用關(guān)鍵詞模糊查詢的時(shí)候,數(shù)據(jù)庫(kù)中有數(shù)據(jù),但是無(wú)法查找出來(lái),本文就來(lái)介紹一下SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空的解決方法
    2025-04-04
  • 在IntelliJ IDEA中.idea文件是什么可以刪除嗎

    在IntelliJ IDEA中.idea文件是什么可以刪除嗎

    相信有很多小伙伴,在用idea寫(xiě)java代碼的時(shí)候,創(chuàng)建工程總是會(huì)出現(xiàn).idea文件,該文件也從來(lái)沒(méi)去打開(kāi)使用過(guò),那么它在我們項(xiàng)目里面,扮演什么角色,到底能不能刪除它呢?這篇文章主要介紹了在IntelliJ IDEA中.idea文件是什么可以刪除嗎,需要的朋友可以參考下
    2024-01-01
  • spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù)

    spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù)

    這篇文章主要介紹了spring AOP實(shí)現(xiàn)@Around輸出請(qǐng)求參數(shù)和返回參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論