验证码修改

This commit is contained in:
2025-12-16 18:26:52 +08:00
parent 62e6365d46
commit f7b0dcd120
10 changed files with 70 additions and 46 deletions

View File

@@ -128,7 +128,8 @@ public class AuthController {
/**
* @description 发送邮箱验证码
* @param requestBody 包含email字段的请求体
* @param requestBody 包含email和scene字段的请求体
* scene: 业务场景login-登录, register-注册, reset-找回密码, bind-绑定邮箱等)
* @return ResultDomain<Boolean> 发送结果
* @author yslg
* @since 2025-11-03
@@ -138,6 +139,7 @@ public class AuthController {
ResultDomain<Map<String, String>> result = new ResultDomain<>();
String email = requestBody.get("email");
String scene = requestBody.get("scene");
// 验证邮箱格式
if (email == null || email.trim().isEmpty()) {
@@ -151,10 +153,15 @@ public class AuthController {
return result;
}
// 验证场景参数
if (scene == null || scene.trim().isEmpty()) {
scene = "default";
}
// 检查是否频繁发送60秒内只能发送一次
String rateLimitKey = "email:code:ratelimit:" + email;
String rateLimitKey = "email:code:ratelimit:" + scene + ":" + email;
if (redisService.hasKey(rateLimitKey)) {
result.fail("验证码已发送,请勿重复发送");
result.fail("验证码已发送,请60秒后再试");
return result;
}
@@ -168,21 +175,25 @@ public class AuthController {
boolean success = emailUtils.sendVerificationCode(email, code);
if (success) {
// 将验证码存储到Redis绑定sessionId有效期5分钟
String codeKey = "email:code:" + sessionId;
String codeValue = email + ":" + code; // 格式:邮箱:验证码
// 将验证码存储到Redis绑定sessionId和业务场景有效期5分钟
String codeKey = "email:code:" + scene + ":" + sessionId;
String codeValue = email + ":" + code;
redisService.set(codeKey, codeValue, 5, TimeUnit.MINUTES);
// 设置5分钟的发送频率限制
redisService.set(rateLimitKey, "1", 5, TimeUnit.MINUTES);
// 设置60秒的发送频率限制
redisService.set(rateLimitKey, "1", 60, TimeUnit.SECONDS);
// 返回sessionId给前端
// 计算过期时间戳(当前时间 + 5分钟
long expireTime = System.currentTimeMillis() + (5 * 60 * 1000);
// 返回sessionId和过期时间给前端
Map<String, String> data = Map.of(
"sessionId", sessionId,
"expireTime", String.valueOf(expireTime),
"message", "验证码已发送到邮箱"
);
logger.info("邮箱验证码已发送,邮箱: {}, sessionId: {}", email, sessionId);
logger.info("邮箱验证码已发送,邮箱: {}, scene: {}, sessionId: {}, expireTime: {}", email, scene, sessionId, expireTime);
result.success("验证码已发送到邮箱", data);
} else {
result.fail("验证码发送失败,请稍后重试");
@@ -193,7 +204,8 @@ public class AuthController {
/**
* @description 发送手机验证码
* @param requestBody 包含phone字段的请求体
* @param requestBody 包含phone和scene字段的请求体
* scene: 业务场景login-登录, register-注册, reset-找回密码, bind-绑定手机等)
* @return ResultDomain<Boolean> 发送结果
* @author yslg
* @since 2025-11-03
@@ -203,6 +215,7 @@ public class AuthController {
ResultDomain<Map<String, String>> result = new ResultDomain<>();
String phone = requestBody.get("phone");
String scene = requestBody.get("scene");
// 验证手机号格式
if (phone == null || phone.trim().isEmpty()) {
@@ -215,10 +228,15 @@ public class AuthController {
return result;
}
// 验证场景参数
if (scene == null || scene.trim().isEmpty()) {
scene = "default";
}
// 检查是否频繁发送60秒内只能发送一次
String rateLimitKey = "sms:code:ratelimit:" + phone;
String rateLimitKey = "sms:code:ratelimit:" + scene + ":" + phone;
if (redisService.hasKey(rateLimitKey)) {
result.fail("验证码已发送,请勿重复发送");
result.fail("验证码已发送,请60秒后再试");
return result;
}
@@ -232,21 +250,25 @@ public class AuthController {
boolean success = smsUtils.sendVerificationCode(phone, code);
if (success) {
// 将验证码存储到Redis绑定sessionId有效期5分钟
String codeKey = "sms:code:" + sessionId;
String codeValue = phone + ":" + code; // 格式:手机号:验证码
// 将验证码存储到Redis绑定sessionId和业务场景有效期5分钟
String codeKey = "sms:code:" + scene + ":" + sessionId;
String codeValue = phone + ":" + code;
redisService.set(codeKey, codeValue, 5, TimeUnit.MINUTES);
// 设置5分钟的发送频率限制
redisService.set(rateLimitKey, "1", 5, TimeUnit.MINUTES);
// 设置60秒的发送频率限制
redisService.set(rateLimitKey, "1", 60, TimeUnit.SECONDS);
// 返回sessionId给前端
// 计算过期时间戳(当前时间 + 5分钟
long expireTime = System.currentTimeMillis() + (5 * 60 * 1000);
// 返回sessionId和过期时间给前端
Map<String, String> data = Map.of(
"sessionId", sessionId,
"expireTime", String.valueOf(expireTime),
"message", "验证码已发送"
);
logger.info("短信验证码已发送,手机号: {}, sessionId: {}", phone, sessionId);
logger.info("短信验证码已发送,手机号: {}, scene: {}, sessionId: {}, expireTime: {}", phone, scene, sessionId, expireTime);
result.success("验证码已发送", data);
} else {
result.fail("验证码发送失败,请稍后重试");
@@ -337,8 +359,8 @@ public class AuthController {
return result;
}
// 通过sessionId验证手机验证码
String smsCodeKey = "sms:code:" + smsSessionId;
// 通过sessionId验证手机验证码(注册场景)
String smsCodeKey = "sms:code:register:" + smsSessionId;
String storedSmsValue = (String) redisService.get(smsCodeKey);
if (storedSmsValue == null) {
result.fail("验证码已过期,请重新获取");
@@ -393,8 +415,8 @@ public class AuthController {
return result;
}
// 通过sessionId验证邮箱验证码
String emailCodeKey = "email:code:" + emailSessionId;
// 通过sessionId验证邮箱验证码(注册场景)
String emailCodeKey = "email:code:register:" + emailSessionId;
String storedEmailValue = (String) redisService.get(emailCodeKey);
if (storedEmailValue == null) {
result.fail("验证码已过期,请重新获取");

View File

@@ -74,8 +74,8 @@ public class EmailLoginStrategy implements LoginStrategy {
return false;
}
// 从Redis获取验证码
String codeKey = "email:code:" + captchaId;
// 从Redis获取验证码(登录场景)
String codeKey = "email:code:login:" + captchaId;
String storedValue = (String) redisService.get(codeKey);
if (storedValue == null) {

View File

@@ -74,8 +74,8 @@ public class PhoneLoginStrategy implements LoginStrategy {
return false;
}
// 从Redis获取验证码
String codeKey = "sms:code:" + captchaId;
// 从Redis获取验证码(登录场景)
String codeKey = "sms:code:login:" + captchaId;
String storedValue = (String) redisService.get(codeKey);
if (storedValue == null) {