短信接口防刷,主要通过两个方面来实现:一个是短信接口加签和时间戳;另外针对短信接口,增加防刷 check 机制;
加签配置很简单,直接将需要控制的接口加到 yml 的参数 jeecg.signUrls 中即可。
目前涉及接口:
/sys/sms
/sys/sendChangePwdSms
同一个 IP 一分钟发送超过 5 次短信,则获取短信接口提示需要验证码
防止刷短信 check 具体逻辑:
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);
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。