我们在开发的时候,会遇到发送短信验证码的情况。如果没有限制,很容易被一些别有用心的人来刷。这样导致短信就会被浪费。所以需要设置发送短信的限制。比如,我们五分钟内只能发送五次短信。

  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;
    }