feat(backend): 注册限流阈值改为可配置

This commit is contained in:
Zhou Weidong committed 2026-10-17 23:22:28 +08:00
1 parent 3403a521eb
commit 758eb69f55
5 files changed
+73 -11

No files matched your search

@@ -25,6 +25,7 @@ import com.fruitshorts.user.vo.LogoutReqVO;
import com.fruitshorts.user.vo.RegisterReqVO;
import com.fruitshorts.user.vo.TokenRespVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@@ -301,10 +302,14 @@ public class AppAuthService {
return resp;
}
/** 每个 IP 24 小时内最多注册几个账号 */
private static final int MAX_REGISTER_PER_IP_PER_DAY = 5;
/** 每台设备 24 小时内最多注册几个账号 */
private static final int MAX_REGISTER_PER_DEVICE_PER_DAY = 3;
/** 每个 IP 24 小时内最多注册几个账号;小于等于 0 表示不限制。 */
@Value("${fruitshorts.auth.register-max-per-ip-per-day:5}")
private int maxRegisterPerIpPerDay = 5;
/** 每台设备 24 小时内最多注册几个账号;小于等于 0 表示不限制。 */
@Value("${fruitshorts.auth.register-max-per-device-per-day:3}")
private int maxRegisterPerDevicePerDay = 3;
private static final int PASSWORD_MIN_LENGTH = 8;
private static final int PASSWORD_MAX_LENGTH = 64;
private static final Pattern HAS_LETTER = Pattern.compile("[A-Za-z]");
@@ -328,7 +333,7 @@ public class AppAuthService {
}
/**
* 注册频控(邮箱免码注册必须带的兜底):同 IP 24h ≤5 个、同设备 24h ≤3 个。
* 注册频控(邮箱免码注册必须带的兜底):阈值由配置提供,≤0 时跳过对应限制。
*
* 直接数 `app_user` 上的 register_ip / register_device_id,不新建计数表:
* 注册量本来就低,这两列也已经有数据,省一张表与一套清理任务。
@@ -337,20 +342,20 @@ public class AppAuthService {
private void guardRegisterRisk(String clientIp, String deviceId) {
LocalDateTime since = LocalDateTime.now().minusDays(1);
String ip = AppIdentifier.nullSafe(clientIp);
if (StringUtils.hasText(ip)) {
if (maxRegisterPerIpPerDay > 0 && StringUtils.hasText(ip)) {
Long byIp = appUserMapper.selectCount(Wrappers.<AppUser>lambdaQuery()
.eq(AppUser::getRegisterIp, ip)
.ge(AppUser::getCreatedAt, since));
if (byIp != null && byIp >= MAX_REGISTER_PER_IP_PER_DAY) {
if (byIp != null && byIp >= maxRegisterPerIpPerDay) {
throw new ServiceException(ErrorCode.TOO_MANY_REQUESTS, "当前网络注册过于频繁,请稍后再试");
}
}
String device = AppIdentifier.nullSafe(deviceId);
if (StringUtils.hasText(device)) {
if (maxRegisterPerDevicePerDay > 0 && StringUtils.hasText(device)) {
Long byDevice = appUserMapper.selectCount(Wrappers.<AppUser>lambdaQuery()
.eq(AppUser::getRegisterDeviceId, device)
.ge(AppUser::getCreatedAt, since));
if (byDevice != null && byDevice >= MAX_REGISTER_PER_DEVICE_PER_DAY) {
if (byDevice != null && byDevice >= maxRegisterPerDevicePerDay) {
throw new ServiceException(ErrorCode.TOO_MANY_REQUESTS, "该设备注册过于频繁,请稍后再试");
}
}