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接口幂等设计与实现
82 0
|
24天前
|
存储 JSON 算法
N 种值得一看的前后端鉴权方案
先赞后看,Java进阶一大半各位hao,我是南哥。记得前几天南哥在牛客看到一条面试题:工作的鉴权怎么做的,了解常用的鉴权方案吗?不得不说,哪怕进入一家小型的互联网公司,他们的鉴权方案这类基础建设早已搭建好,在工作中用到的更多是前人搭建好的方案。遇到这道题,如果自己没去提前了解,回答起来容易太浅显。
N 种值得一看的前后端鉴权方案
|
6月前
|
缓存 NoSQL 前端开发
《优化接口设计的思路》系列:第六篇—接口防抖(防重复提交)的一些方式
本文探讨了后端开发中的接口防抖策略,作者是一名有六年经验的Java开发者,分享了如何防止重复提交导致的问题。防抖主要用于避免用户误操作或网络波动引起的多次请求,作者提出理想防抖机制应具备正确性、响应速度、易集成和用户反馈。文章详细分析了哪些接口需要防抖(如用户输入、按钮点击、滚动加载)以及如何识别重复接口,提出了使用共享缓存和分布式锁两种实现方式,并展示了基于Redis的Java代码示例。作者通过注解实现请求锁,并提供了测试截图证明防抖效果。然而,实现完全幂等性还需要业务层面的补充措施。
471 7
|
7月前
|
数据采集 存储 NoSQL
如何优雅实现接口防刷
一文讲清楚如何用redis实现接口防刷
87 0
如何优雅实现接口防刷
|
小程序 JavaScript
借助云开发10行代码实现短信验证码的发送
借助云开发10行代码实现短信验证码的发送
|
安全 NoSQL Redis
优雅的接口防刷处理方案! 下
优雅的接口防刷处理方案! 下
|
消息中间件 安全 JavaScript
优雅的接口防刷处理方案! 上
优雅的接口防刷处理方案! 上
|
NoSQL 安全 Java
优雅的接口防刷处理方案 下
优雅的接口防刷处理方案 下
|
JavaScript 小程序 NoSQL
优雅的接口防刷处理方案 上
优雅的接口防刷处理方案 上