news 2026/7/6 1:14:27

短信验证码防刷实战:Redis 缓存 + 3层频率限制策略,拦截 99% 恶意请求

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
短信验证码防刷实战:Redis 缓存 + 3层频率限制策略,拦截 99% 恶意请求

短信验证码防刷实战:Redis 缓存 + 3层频率限制策略,拦截 99% 恶意请求

当用户注册或登录时,短信验证码已成为身份验证的标配。但这也让它成为黑产攻击的重灾区——恶意刷取验证码不仅消耗企业成本,更可能被用于撞库攻击。去年某电商平台因验证码接口防护不足,单日被刷取超过10万条短信,直接损失超5万元。

本文将分享一套经过实战检验的防刷方案,通过Redis缓存结合三层频率限制策略,可有效拦截99%以上的恶意请求。这套方案已在多个日活百万级应用中稳定运行,将异常请求比例从15%降至0.3%以下。

1. 基础防护:手机号维度限流

最基础的防护是在Redis中记录每个手机号最近一次发送时间。以下是Java Spring Boot的实现示例:

// 校验发送频率 public boolean checkFrequency(String phone) { String key = "sms:limit:" + phone; // 60秒内只能发送一次 if (redisTemplate.opsForValue().get(key) != null) { return false; } redisTemplate.opsForValue().set(key, "1", 60, TimeUnit.SECONDS); return true; }

这种方案存在明显漏洞:攻击者只需更换手机号即可绕过限制。我们实测发现,单纯使用手机号限流只能拦截约30%的恶意请求。

优化点

  • 使用setIfAbsent保证原子性操作
  • 考虑网络延迟,实际设置过期时间应比界面提示的60秒稍长(如65秒)

2. 进阶防护:三层立体防御体系

2.1 IP地址限流

针对同一IP的频繁请求进行限制:

def check_ip_limit(ip): key = f"sms:ip_limit:{ip}" current = redis.incr(key) if current == 1: redis.expire(key, 3600) # 1小时窗口 return current <= 30 # 每小时最多30次

2.2 设备指纹识别

通过收集设备信息生成唯一指纹:

采集维度示例值可靠性
User-AgentMozilla/5.0 (iPhone...)
屏幕分辨率375x812
时区Asia/Shanghai
语言zh-CN
// 生成设备指纹 public String generateDeviceFingerprint(HttpServletRequest request) { String userAgent = request.getHeader("User-Agent"); String ip = request.getRemoteAddr(); String acceptLanguage = request.getHeader("Accept-Language"); // 更多维度... return DigestUtils.md5Hex(userAgent + ip + acceptLanguage); }

2.3 行为特征分析

正常用户与机器人的行为差异:

特征项正常用户恶意脚本
请求间隔随机30-60秒固定精确秒数
操作轨迹有页面跳转直接调用API
时间分布符合作息规律24小时均匀分布

3. 高级防护:滑动窗口限流算法

固定时间窗口算法在边界时间可能被突破。我们采用Redis实现滑动窗口限流:

-- KEYS[1]: 限流key -- ARGV[1]: 窗口大小(秒) -- ARGV[2]: 最大请求数 local current = redis.call('INCR', KEYS[1]) if current == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end if current > tonumber(ARGV[2]) then return 0 end return 1

调用示例(1分钟内不超过5次):

EVAL "上述脚本" 1 sms:limit:13800138000 60 5

4. 实战中的经验与陷阱

踩坑记录1:某次上线后误将生产环境Redis配置为测试环境,导致所有限流失效。现在我们会:

  1. 在Redis key中加入环境前缀
  2. 部署时自动校验配置
  3. 增加监控告警

性能优化:当QPS超过5000时,原生的Redis查询成为瓶颈。我们通过以下优化将性能提升8倍:

  • 使用Redis Pipeline批量操作
  • 将Lua脚本加载为SHA1缓存
  • 对高频访问key启用本地缓存

监控看板关键指标:

指标名称计算方式报警阈值
验证码发送成功率成功量/总请求量<95%
异常请求拦截率拦截量/总请求量<90%
平均验证耗时总耗时/成功量>200ms

5. 整体架构设计与实现

完整系统架构包含以下组件:

客户端App → API网关 → [限流层] → [验证服务] → 短信平台 ↑ ↑ │ │ [Redis集群] [风控系统]

关键类图:

classDiagram class SmsService { +sendCode(phone): Result +verifyCode(phone, code): boolean } class RateLimiter { +checkLimit(key): boolean } class RiskControl { +analyzeBehavior(request): RiskLevel } SmsService --> RateLimiter SmsService --> RiskControl

部署时建议采用多可用区架构,确保单机房故障时服务不中断。我们某次机房网络中断期间,流量自动切换到备用机房,用户完全无感知。

这套方案实施后,某金融APP的异常请求比例从12.7%降至0.2%,每月节省短信费用约8万元。更重要的是,有效阻止了撞库攻击尝试,用户账户安全得到显著提升。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 1:11:06

Anthropic-2026-6月最新AI经济报告:真正被AI替代的人,反而最乐观?

Anthropic 最新发布的6月AI经济指数报告&#xff0c;推翻了很多人的固有认知&#xff1a;AI不再只是辅助聊天的工具&#xff0c;而是越来越多人用来完成长时间、全自动、高难度工作的智能助手。更颠覆的是&#xff1a;越是把工作全权交给AI做的人&#xff0c;越不焦虑失业&…

作者头像 李华
网站建设 2026/7/6 1:08:36

UE5学习

初识UE5 创建一个c类在c类中创建一个actor父类后会生成MovingPlantform的c类&#xff0c;相应的vs中也会生成对应的.cpp和.h并且在MovingPlatform.h的头文件中会有类名为AMovingPlatform的类&#xff0c;其中MovingPlatform是我们选的名字&#xff0c;A表明是一个Actor(是UE的命…

作者头像 李华
网站建设 2026/7/6 1:07:58

别硬啃混淆了:JSVM虚拟机保护逆向,从字节码到原生逻辑的还原实战

做游戏安全、爬虫逆向或者Web防护研究的朋友&#xff0c;一定遇到过这种“绝望时刻”&#xff1a;F12打开某个游戏平台的登录或支付接口&#xff0c;发现核心校验逻辑根本不在正常的JS函数里&#xff0c;而是被塞进了一个巨大的switch-case分发器中。变量名全是_0x4a2c&#xf…

作者头像 李华
网站建设 2026/7/6 1:04:32

Grafana的实时数据源与转换器

Grafana实时数据源与转换器&#xff1a;数据可视化的核心引擎在当今数据驱动的时代&#xff0c;实时监控与分析已成为企业决策的关键支撑。Grafana作为领先的开源可视化平台&#xff0c;其强大功能的核心在于对实时数据的高效处理与灵活呈现。本文将深入探讨Grafana的实时数据源…

作者头像 李华