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);
    }
}
目录
相关文章
|
安全 NoSQL API
互联网并发与安全系列教程(08) - API接口幂等设计与实现
互联网并发与安全系列教程(08) - API接口幂等设计与实现
75 0
|
1天前
|
存储 JSON 算法
N 种值得一看的前后端鉴权方案
先赞后看,Java进阶一大半各位hao,我是南哥。记得前几天南哥在牛客看到一条面试题:工作的鉴权怎么做的,了解常用的鉴权方案吗?不得不说,哪怕进入一家小型的互联网公司,他们的鉴权方案这类基础建设早已搭建好,在工作中用到的更多是前人搭建好的方案。遇到这道题,如果自己没去提前了解,回答起来容易太浅显。
N 种值得一看的前后端鉴权方案
|
6月前
|
数据采集 存储 NoSQL
如何优雅实现接口防刷
一文讲清楚如何用redis实现接口防刷
80 0
如何优雅实现接口防刷
|
6月前
|
缓存 监控 测试技术
ERP系统对接方案与API接口封装系列(高并发)
企业资源规划(ERP)系统是现代企业管理的核心,它集成了企业内部的各个部门和业务流程。为了实现ERP系统与其他外部系统或应用程序之间的数据交换和协作,需要对接方案。API(应用程序编程接口)是实现系统对接的常用方法之一。
|
算法 NoSQL API
微信支付-业务流程图+时序图梳理微信支付链路+封装对接微信API工具类
微信支付-业务流程图+时序图梳理微信支付链路+封装对接微信API工具类
521 0
|
安全 NoSQL Redis
优雅的接口防刷处理方案! 下
优雅的接口防刷处理方案! 下
|
消息中间件 安全 JavaScript
优雅的接口防刷处理方案! 上
优雅的接口防刷处理方案! 上
|
JavaScript 小程序 NoSQL
优雅的接口防刷处理方案 上
优雅的接口防刷处理方案 上
|
NoSQL 安全 Java
优雅的接口防刷处理方案 下
优雅的接口防刷处理方案 下
下一篇
无影云桌面