我们在开发的时候,会遇到发送短信验证码的情况。如果没有限制,很容易被一些别有用心的人来刷。这样导致短信就会被浪费。所以需要设置发送短信的限制。比如,我们五分钟内只能发送五次短信。
1:需要引入的jar包
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2:引入redis的配置类
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableCaching
public class RedisInitializer extends CachingConfigurerSupport {
@Autowired
LettuceConnectionFactory redisConnectionFactory;
@Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// value值的序列化采用GenericJackson2JsonRedisSerializer
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
// 开启事务特性
//template.setEnableTransactionSupport(true);
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
3:配置redis
spring.redis.cluster.nodes=redis的ip+端口
spring.redis.password=redis的密码
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=1000
spring.redis.lettuce.pool.max-wait=60s
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=4
4:实现发送短信限制功能。
public Result sendMsg(String phoneNumber) {
try {
//电话号码验证
String regex = "^[1]\\d{10}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phoneNumber);
if (!matcher.matches()) {
return Result.sendFailure("无效的手机号");
}
Integer regId = registrationMapperExt.checkPhone(phoneNumber);
if(regId!=null){
logger.info("手机号:"+phoneNumber+"被:"+regId+" 绑定!");
return Result.sendFailure("手机号已经被绑定!");
}
//设置redis中手机号存储的次数
long count=redisTemplate.boundValueOps(Constant.SMS_LIMIT_NO + phoneNumber ).increment(1);
if(count==1){
//设置 5 分钟过期
redisTemplate.expire(Constant.SMS_LIMIT_NO + phoneNumber, 60*5 , TimeUnit.SECONDS);
}
//5分钟内连续发送5次短息,则发送频繁
if(count > 5){
logger.info("验证码发送频繁,超过了限定的次数");
return Result.sendFailure("验证码发送频繁,超过了限定的次数,稍后再试");
}
//发送短信
String template = "尊敬的用户你号。你的验证码是:[checkCode]";
//验证码生成
String code = generatorSmsCode();
template = template.replace("[checkCode]", code);
try {
JSONObject jsonObject = smsUtil.sendEmail(template, phoneNumber);
if (!(boolean) jsonObject.get("success")) {
logger.info("发送短信失败:" + jsonObject.toJSONString());
return Result.sendFailure("发送短信失败");
}
} catch (Exception e) {
logger.error(e.getMessage());
return Result.sendFailure("发送短信失败。");
}
//redis存储
logger.info("手机号:" + phoneNumber + "的短信验证码是:" + code);
redisTemplate.opsForValue().set(Constant.BIND_PHONE_KEY + phoneNumber, code);
//4:在redis中设置失效时间
Integer time = 5;
//设置过期时间
redisTemplate.expire(Constant.BIND_PHONE_KEY + phoneNumber, 60 * time, TimeUnit.SECONDS);
return Result.sendSuccess("发送短信成功!");
} catch (Exception e) {
logger.error(e.getMessage());
return Result.sendFailure("发送短信失败。");
}
}
生成短线码的方法
//短信验证码的方法,随机六位数字
private String generatorSmsCode() {
String code = "";
for (int i = 0; i < Integer.parseInt("6"); i++) {
code += new Random().nextInt(10);
}
return code;
}