首次提交
This commit is contained in:
commit
1101681331
131 changed files with 7017 additions and 0 deletions
|
|
@ -0,0 +1,76 @@
|
|||
package com.xjhs.findmemerchant.security.sms;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Random;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SmsCodeService {
|
||||
|
||||
/** Redis key 前缀:sms:code:{scene}:{phone} */
|
||||
private static final String SMS_CODE_KEY_PREFIX = "sms:code:";
|
||||
|
||||
/** 验证码有效期:5 分钟 */
|
||||
private static final Duration SMS_CODE_TTL = Duration.ofMinutes(5);
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final Random random = new Random();
|
||||
private Object smsSender; // 你自己的短信通道接口
|
||||
|
||||
|
||||
private String buildKey(String phone, String scene) {
|
||||
return SMS_CODE_KEY_PREFIX + scene + ":" + phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 6 位数字验证码
|
||||
*/
|
||||
private String generateCode() {
|
||||
return String.format("%06d", random.nextInt(1_000_000));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码:生成 -> 存 Redis -> 调短信通道发出去
|
||||
*/
|
||||
public void sendVerificationCode(String phone, String scene) {
|
||||
var code = generateCode();
|
||||
var key = buildKey(phone, scene);
|
||||
// 存到 Redis,设置 TTL
|
||||
redisTemplate.opsForValue().set(key, code, SMS_CODE_TTL);
|
||||
|
||||
// TODO:调用你自己的短信通道(阿里云、腾讯云等)
|
||||
// smsSender.sendSmsCode(phone, scene, code);
|
||||
|
||||
// 开发阶段也可以打印一下方便调试
|
||||
log.debug("send sms code, phone={},scene={},code={}", phone,scene, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码:
|
||||
* - key 不存在 => 过期 / 未发送 => 抛 SmsCodeExpiredException
|
||||
* - code 不匹配 => 抛 SmsCodeInvalidException
|
||||
* - 匹配 => 删除 key(一次性)
|
||||
*/
|
||||
public void verifyCode(String phone, String scene, String inputCode) throws Exception {
|
||||
String key = buildKey(phone, scene);
|
||||
String realCode = redisTemplate.opsForValue().get(key);
|
||||
if (realCode == null) {
|
||||
// 对齐 Go 里的 ErrSMSCodeExpired
|
||||
throw new Exception("验证码已过期或未发送");
|
||||
}
|
||||
|
||||
if (!realCode.equals(inputCode)) {
|
||||
// 不正确,但不删除,让用户继续尝试(错误次数由 AuthService 控制)
|
||||
throw new Exception("验证码错误");
|
||||
}
|
||||
// 验证通过,删除验证码(一次性)
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue