JeecgBoot 短信验证码接口,如何实现防刷机制?

简介: 短信接口防刷,主要通过两个方面来实现:一个是短信接口加签和时间戳;另外针对短信接口,增加防刷 check 机制

短信接口防刷,主要通过两个方面来实现:一个是短信接口加签和时间戳;另外针对短信接口,增加防刷 check 机制;

具体如下:

一、针对短信接口加签和时间戳

加签配置很简单,直接将需要控制的接口加到 yml 的参数 jeecg.signUrls 中即可。

目前涉及接口:

/sys/sms
/sys/sendChangePwdSms

二、短信接口增加高频校验

同一个 IP 一分钟发送超过 5 次短信,则获取短信接口提示需要验证码

防止刷短信 check 具体逻辑:

  • 同一 IP,一分钟内发短信不允许超过 5 次(每一分钟重置每个 IP 请求次数)
  • 同一 IP,一分钟内发短信超过 20 次,进入黑名单,不让使用短信接口
2.1 在发送短信的地方,增加高频 check

2.2 获取短信的验证码接口

2.3 防止刷短信工具类实现如下
package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 防止刷短信工具
 * 
 * 1、同一IP,1分钟内发短信不允许超过5次(每一分钟重置每个IP请求次数)
 * 2、同一IP,1分钟内发短信超过20次,进入黑名单,不让使用短信接口
 */
@Slf4j
public class DySmsLimit {
    // 1分钟内最大发短信数量(单一IP)
    private static final int MAX_MESSAGE_PER_MINUTE = 5;
    // 1分钟
    private static final int MILLIS_PER_MINUTE = 60000;
    // 一分钟内报警线最大短信数量,超了进黑名单(单一IP)
    private static final int MAX_TOTAL_MESSAGE_PER_MINUTE = 20;
    private static ConcurrentHashMap<String, Long> ipLastRequestTime = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Integer> ipRequestCount = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Boolean> ipBlacklist = new ConcurrentHashMap<>();
    /**
     * @param ip 请求发短信的IP地址
     * @return
     */
    public static boolean canSendSms(String ip) {
        long currentTime = System.currentTimeMillis();
        long lastRequestTime = ipLastRequestTime.getOrDefault(ip, 0L);
        int requestCount = ipRequestCount.getOrDefault(ip, 0);
        log.info("IP:{}, Msg requestCount:{} ", ip, requestCount);
        if (ipBlacklist.getOrDefault(ip, false)) {
            // 如果IP在黑名单中,则禁止发送短信
            log.error("IP:{}, 进入黑名单,禁止发送请求短信!", ip);
            return false;
        }
        if (currentTime - lastRequestTime >= MILLIS_PER_MINUTE) {
            // 如果距离上次请求已经超过一分钟,则重置计数
            ipRequestCount.put(ip, 1);
            ipLastRequestTime.put(ip, currentTime);
            return true;
        } else {
            // 如果距离上次请求不到一分钟
            ipRequestCount.put(ip, requestCount + 1);
            if (requestCount < MAX_MESSAGE_PER_MINUTE) {
                // 如果请求次数小于5次,允许发送短信
                return true;
            } else if (requestCount >= MAX_TOTAL_MESSAGE_PER_MINUTE) {
                // 如果请求次数超过报警线短信数量,将IP加入黑名单
                ipBlacklist.put(ip, true);
                return false;
            } else {
                log.error("IP:{}, 1分钟内请求短信超过5次,请稍后重试!", ip);
                return false;
            }
        }
    }
    /**
     * 图片二维码验证成功之后清空数量
     * 
     * @param ip IP地址
     */
    public static void clearSendSmsCount(String ip) {
        long currentTime = System.currentTimeMillis();
        ipRequestCount.put(ip, 0);
        ipLastRequestTime.put(ip, currentTime);
    }
}
目录
相关文章
|
11月前
|
安全 NoSQL API
互联网并发与安全系列教程(08) - API接口幂等设计与实现
互联网并发与安全系列教程(08) - API接口幂等设计与实现
73 0
|
4月前
|
缓存 NoSQL 前端开发
《优化接口设计的思路》系列:第六篇—接口防抖(防重复提交)的一些方式
本文探讨了后端开发中的接口防抖策略,作者是一名有六年经验的Java开发者,分享了如何防止重复提交导致的问题。防抖主要用于避免用户误操作或网络波动引起的多次请求,作者提出理想防抖机制应具备正确性、响应速度、易集成和用户反馈。文章详细分析了哪些接口需要防抖(如用户输入、按钮点击、滚动加载)以及如何识别重复接口,提出了使用共享缓存和分布式锁两种实现方式,并展示了基于Redis的Java代码示例。作者通过注解实现请求锁,并提供了测试截图证明防抖效果。然而,实现完全幂等性还需要业务层面的补充措施。
358 7
|
5月前
|
数据采集 存储 NoSQL
如何优雅实现接口防刷
一文讲清楚如何用redis实现接口防刷
72 0
如何优雅实现接口防刷
|
5月前
|
数据可视化 数据挖掘 物联网
API接口:原理、设计与应用
随着互联网技术的发展,应用程序之间的交互变得越来越频繁。API(应用程序编程接口)作为不同应用程序之间的桥梁,发挥着越来越重要的作用。本文将详细介绍API接口的原理、设计与应用,并通过部分代码示例帮助读者更好地理解。
|
消息中间件 安全 JavaScript
优雅的接口防刷处理方案! 上
优雅的接口防刷处理方案! 上
|
安全 NoSQL Redis
优雅的接口防刷处理方案! 下
优雅的接口防刷处理方案! 下
|
JavaScript 小程序 NoSQL
优雅的接口防刷处理方案 上
优雅的接口防刷处理方案 上
|
NoSQL 安全 Java
优雅的接口防刷处理方案 下
优雅的接口防刷处理方案 下
|
小程序 开发者
微信小程序模板消息接口下线了,不用慌,调用统一服务消息接口来实现相同功能
做过微信开发的应该都有一点感触,就是他的开发文档不是一成不变的,接口有时候会被下线,但也不是一下子就不能用了,一般会兼容旧接口,然后提醒你使用新接口有更多好处。如果接口真的直接下线了,也会提供另一种能够实现相同功能的接口给你替换。所以有天你以为代码都写好了,没有bug了,悠哉悠哉的时候,忽然产品经理说微信的哪个接口不能用了,快去改一下,不要惊讶,老老实实去改就对了哈。
669 0
微信小程序模板消息接口下线了,不用慌,调用统一服务消息接口来实现相同功能