使用 Flask-Limiter 和 Nginx 实现接口访问次数限制
在现代 Web 应用中,针对敏感接口(如短信验证码、登录接口等)的访问次数限制至关重要。通过设置合理的限流策略,可以有效防止接口滥用,避免过多的资源消耗,并提升安全性。本文将通过 Nginx 和 Flask-Limiter 为 Flask 应用实现 IP 级别的限流,同时确保限流基于客户端的真实 IP 地址,而非内网地址如 172.17.0.1
。
1. 使用 Nginx 作为反向代理
Nginx 通常作为 Web 应用的反向代理,接收来自客户端的请求并将其转发到后端的应用程序(如 Flask)。由于 Nginx 在中间充当代理角色,后端应用获取到的可能是 Nginx 或 Docker 容器的内网 IP(如 172.17.0.1
),因此获取客户端真实 IP 就显得非常重要。
Nginx 配置中的关键参数
我们可以通过一些配置,将客户端的真实 IP 地址传递给 Flask 应用:
# 重定向 HTTP 到 HTTPS
server {listen 80;server_name example.com;return 301 https://$host$request_uri;
}# 处理 HTTPS 请求
server {listen 443 ssl http2;server_name example.com;# SSL 证书配置ssl_certificate /path/to/your/fullchain.pem;ssl_certificate_key /path/to/your/privkey.pem;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20:!aNULL:!MD5:!DSS;ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;add_header Strict-Transport-Security "max-age=31536000" always;# 反向代理到 Flask 应用的 5100 端口location / {proxy_pass http://127.0.0.1:5100; # 将请求转发到 Flaskproxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}# 日志配置(可选)access_log /path/to/log/access.log;error_log /path/to/log/error.log;
}
主要参数解释
proxy_pass
: 将请求转发到后端的 Flask 应用,通常监听在127.0.0.1:5100
端口。proxy_set_header Host $host
: 将客户端请求的主机名传递给后端应用。proxy_set_header X-Real-IP $remote_addr
: 传递客户端的真实 IP 地址给后端应用。$remote_addr
是直接连接到 Nginx 的客户端 IP,通常是原始客户端的 IP。proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
: 将经过的代理链(包括客户端真实 IP)传递给后端应用。这个头通常包含客户端的真实 IP 地址。proxy_set_header X-Forwarded-Proto $scheme
: 传递请求使用的协议(HTTP 或 HTTPS)给后端应用。
避免内网 IP 地址 172.17.0.1
如果您的 Flask 应用运行在 Docker 容器中,而 Nginx 也运行在同一服务器上,后端 Flask 应用接收到的 IP 可能是 172.17.0.1
,这是 Docker 内网的默认网关地址。这个地址会导致所有请求都被认为来自同一个 IP,从而错误地进行限流。
通过上述 Nginx 配置中的 X-Forwarded-For
头部,我们可以将客户端的真实 IP 地址传递给 Flask,避免使用 Docker 内部的 IP(如 172.17.0.1
)进行限流。
2. 使用 Flask-Limiter 实现限流
Flask-Limiter
是一个非常方便的库,用于限制 Web 应用中的接口访问次数。我们可以结合 Nginx 的配置,通过 X-Forwarded-For
获取到真实的客户端 IP,基于 IP 实现限流。
安装 Flask-Limiter
首先,确保 Flask-Limiter
已安装:
pip install flask-limiter
基于 IP 地址限流的 Flask 代码
from flask import Flask, request, jsonify
from flask_limiter import Limiterapp = Flask(__name__)# 获取真实客户端 IP 地址
def get_client_ip():# 检查是否有 X-Forwarded-For 头部if request.headers.getlist("X-Forwarded-For"):return request.headers.getlist("X-Forwarded-For")[0] # 获取真实的客户端 IPelse:return request.remote_addr # 使用默认的 remote_addr# 初始化 Flask-Limiter,并使用 get_client_ip 作为限流的 key_func
limiter = Limiter(key_func=get_client_ip, # 使用真实的客户端 IP 进行限流app=app,storage_uri="redis://<your_redis_host>:<redis_port>/1" # 使用 Redis 存储限流信息
)# 定义接口,并为每个 IP 地址限制每分钟 1 次,每天最多 15 次访问
@app.route('/send_verification_code', methods=['POST'])
@limiter.limit("1 per minute; 15 per day")
def send_verification_code():phone_number = request.form.get('phone_number')machine_id = request.headers.get('Machine-Id')if not phone_number:return jsonify({"error": "手机号不能为空"}), 400if not machine_id:return jsonify({"error": "Machine-Id 不能为空"}), 400# 处理发送验证码的逻辑return jsonify({"message": "验证码发送成功"}), 200if __name__ == '__main__':app.run(debug=True)
代码解释
-
get_client_ip
函数: 用于获取真实的客户端 IP,优先使用X-Forwarded-For
头部中的第一个 IP 地址(通常为客户端 IP),如果没有,则使用request.remote_addr
。 -
Flask-Limiter
配置:key_func
设置为get_client_ip
,确保限流基于客户端的真实 IP。storage_uri
指定 Redis 存储限流信息,避免 Flask 重启或进程切换时丢失限流数据。 -
@limiter.limit("1 per minute; 15 per day")
: 设置限流规则,限制每个 IP 每分钟只能请求一次,每天最多 15 次。
3. Redis 存储限流信息
Flask-Limiter
支持使用 Redis 存储限流信息,这样即使 Flask 应用重启,限流信息也不会丢失。通过 Redis 可以实现跨进程的限流。
Redis 连接配置
limiter = Limiter(key_func=get_client_ip,app=app,storage_uri="redis://:password@redis_host:6379/1" # 使用 Redis db1
)
4. 验证限流
通过上述配置,当 Flask-Limiter 生效时,Redis 中的键将会包含真实的客户端 IP,并记录请求的访问次数。例如,Redis 中的键可能类似于:
LIMITS:LIMITER/<client_real_ip>/send_verification_code/1/1/minute
这样,限流规则是基于客户端真实 IP 地址的,避免了因 Docker 内网 IP 172.17.0.1
导致的限流错误。
5. 总结
通过 Nginx 的反向代理配置,我们可以将客户端的真实 IP 传递给 Flask 应用。结合 Flask-Limiter
,可以基于客户端的真实 IP 地址,实现针对敏感接口的访问频率限制。这样不仅可以提升 Web 应用的安全性,还能有效防止滥用行为。
核心步骤总结如下:
- Nginx 配置: 使用
X-Forwarded-For
和X-Real-IP
头部传递客户端 IP,避免使用172.17.0.1
等内网 IP。 - Flask-Limiter: 结合 Redis 实现基于 IP 地址的访问次数限制。
- 客户端真实 IP 获取: 通过
get_client_ip
函数确保 Flask 获取到真实的客户端 IP。
这种限流机制为 Web 应用的安全和性能提供了重要保障。
相关文章:
使用 Flask-Limiter 和 Nginx 实现接口访问次数限制
在现代 Web 应用中,针对敏感接口(如短信验证码、登录接口等)的访问次数限制至关重要。通过设置合理的限流策略,可以有效防止接口滥用,避免过多的资源消耗,并提升安全性。本文将通过 Nginx 和 Flask-Limiter…...

【数据结构】排序算法---冒泡排序
文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 1. 定义 冒泡排序(英语:Bubble sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的…...
mysql数据库中事务锁的机制
读锁又称为共享锁,简称S锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。 写锁又称为排他锁,简称X锁,排他锁就是不能与其他所并存,如一个事务获取了一个…...
并发工具类-CountDownLatch
CountDownLatch 是 Java 中提供的一种非常有用的并发工具类,位于 java.util.concurrent 包中。它可以使一个或多个线程等待其他线程完成一组特定的操作后再继续执行。CountDownLatch 通过维护一个计数器来实现这一点,计数器的初始值由构造函数设定。每当…...

进程的重要函数
进程的重要函数: fork函数 了解fork函数 通过调用fork()函数,则会产生一个新的进程。调用fork()函数的进程叫做 父进程,产生的新进程则为子进程。 其编码过程: 1.函数功能: 函数头文件 #include <sys/types.h> #include <unistd.h> 函数…...
python 实现average median平均中位数算法
average median平均中位数算法介绍 平均(Mean)和中位数(Median)是统计学中常用的两个概念,用于描述一组数据的中心趋势,但它们并不是算法,而是数据处理的结果。不过,我可以解释如何…...
HTML概述
1. HTML概述 1.1 HTML定义 HTML超文本标记语言,其中超文本是链接,标记也叫标签(即带尖括号的文本)。 1.2 HTML基本骨架 HTML基本骨架是网页模板。 <html><head><title>网页的标题</title></head&…...

【FFT】信号处理——快速傅里叶变换【通俗易懂】
快速傅里叶变换(Fast Fourier Transform, FFT)是一种用于将信号从时间域转换到频率域的算法。 傅里叶变换的核心思想是:任何周期性信号都可以分解成多个不同频率的正弦波或余弦波的叠加。 简单来说,FFT可以帮助我们理解一个信号…...
电脑升级WIN11之后需要注意哪些东西
1.记事本,在前单位时,电脑升级后,记事本会需要手动更新,或手动安装 2.任务栏,WIN11默认任务栏在中间位置,想要调成WIN10一样的位置,分享两个方法 拖拽法(适用于Windows 11 2022年1…...
GEE 教程:利用sentinel-5p数据进行长时序CO一氧化碳的监测分析并结合夜间灯光数据分析
目录 简介 数据 哨兵5号 NOAA/VIIRS/DNB/MONTHLY_V1/VCMCF 函数 ui.Chart.image.series(imageCollection, region, reducer, scale, xProperty) Arguments: Returns: ui.Chart 代码 结果 简介 利用sentinel-5p数据进行长时序CO一氧化碳的监测分析并结合夜间灯光数据…...

【教程】鸿蒙ARKTS 打造数据驾驶舱---前序
鸿蒙ARKTS 打造数据驾驶舱 前面2章我介绍了如何通过定义View绘制箭头以及圆形进度,初步了解了鸿蒙如何进行自定义View。接下来我将通过我最近在带的一个VUE的项目,简单实现了几个鸿蒙原生页面。帮助大家快速上手纯血鸿蒙开发. 本项目基于Api11Stage模…...

Html css样式总结
1.Html css样式总结 CSS 定义 中文名称:层叠样式表 。 英文全称:Cascading Style Sheets ,简称CSS。在网页制作时采用CSS技术,可以有效地对页面的布局、字体、颜色、背景和其它效果实现更加精确的控制。 (1)…...
决策树基础概论
1. 概述 在机器学习领域,决策树(Decision Tree) 是一种高度直观且广泛应用的算法。它通过一系列简单的是/否问题,将复杂的决策过程分解为一棵树状结构,使得分类或回归问题的解决过程直观明了。决策树的最大特点在于可…...

Spring Boot集成Akka Cluster快速入门Demo
1.什么是Akka Cluster? Akka Cluster将多个JVM连接整合在一起,实现消息地址的透明化和统一化使用管理,集成一体化的消息驱动系统。最终目的是将一个大型程序分割成若干子程序,部署到很多JVM上去实现程序的分布式并行运算…...

django学习入门系列之第十点《A 案例: 员工管理系统10》
文章目录 12 管理员操作12.4 密码加密12.5 获取对象(防止id错误--编辑界面等)12.6 编辑管理员12.7 重置密码 往期回顾 12 管理员操作 12.4 密码加密 密码不应该以明文的方式直接存储到数据库,应该加密才放进去 定义一个md5的方法ÿ…...

Unity实战案例全解析:PVZ 植物卡片状态分析
Siki学院2023的PVZ免费了,学一下也坏 卡片状态 卡片可以有三种状态: 1.阳光足够,(且cd好了可以种植) 2.阳光不够,(cd?好了:没好 (三目运算符)&…...

判断变量是否为有限数字(非无穷大或NaN)math.isfinite() 判断变量是否为无穷大(正无穷大或负无穷大)math.isinf()
【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 判断变量是否为有限数字(非无穷大或NaN) math.isfinite() 判断变量是否为无穷大(正无穷大或负无穷大) math.isinf() 请问关于以下代码表述错误…...

idea使用阿里云服务器运行jar包
说明:因为我用的阿里云服务器不是自己的,所以一些具体的操作可能不太全面。看到一个很完整的教程,供参考。 0. 打包项目 这里使用的是maven打包。 在pom.xml中添加以下模块。 <build><plugins><plugin><groupId>org…...

解决nginx代理SSE接口的响应没有流式返回
目录 现象原来的nginx配置解决 现象 前后端分离的项目,前端访问被nginx反向代理的后端SSE接口,预期是流式返回,但经常是很久不响应,一响应全部结果一下子都返回了。查看后端项目的日志,响应其实是流式产生的。推测是n…...

11 - TCPClient实验
在上一个章节的UDP通信测试中,尽管通信的实现过程相对简洁,但出现了通信数据丢包的问题。因此,本章节将基于之前建立的WIFI网络连接,构建一个基础的TCPClient连接机制。我们利用网络调试助手工具来发送数据,测试网络通…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...