1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 使用Springboot StringRedisTemplate 在单位时间内对发送手机号验证码次数做限制

使用Springboot StringRedisTemplate 在单位时间内对发送手机号验证码次数做限制

时间:2021-11-22 14:38:18

相关推荐

使用Springboot StringRedisTemplate 在单位时间内对发送手机号验证码次数做限制

通常我们在做通过手机号检验,发送短信验证码之类接口的时候,在单位时间内,要对发送的次数做限制,防止恶意刷接口,短信类接口毕竟还是收费的。

首先我们需要在springboot 项目中引入Redis

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--springboot2.X默认使用lettuce连接池,需要引入commons-pool2--><dependency><groupId>mons</groupId><artifactId>commons-pool2</artifactId></dependency>

然后在配置文件中配置你redis的地址端口 密码 等

# Redisspring:redis:database: 0host: localhostpassword: Botao@port: 6379timeout: 300lettuce:pool:max-active: 200 #连接池最大连接数(使用负值表示没有限制)max-idle: 20 # 连接池中的最大空闲连接min-idle: 5 #连接池中的最小空闲连接max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)

windows 环境安装redis 及配置用户名密码,可以看这

整个流程是,首先我们生成4位的短信验证码,然后把要发送的手机号 验证码 设置过期时间存入redis ,同时将 手机号,发送的次数同时存入redis 注入两次存入的key 不一样 然后我们设置存入次数 key的过期时间 ,当然我们在发送前,需要查询单位时间内发送的次数有没有超过限制 ,没有限制再发

如图所示

@RestController@RequestMapping("/app")public class SendSMSController {private static final Logger log = LoggerFactory.getLogger(SendSMSController.class);private static final String SYMBOLS = "0123456789";private static final Random RANDOM = new SecureRandom();@Value("${sms_apikey}")private String apikey;@Value("${sms_send}")private String send;@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 发送短信验证码* @param userId* @param phone* @return*/@PostMapping("sys/sendSms")public AjaxResult SendSms(String userId, String phone){try {log.info("用户发送短信验证码:"+userId+","+phone);if(StringUtils.isBlank(phone)){log.info("参数错误");return AjaxResult.error("参数错误");}//设置key 自动 +1long count=stringRedisTemplate.boundValueOps(AppConstants.REDIS_SMS_USER_PREFIX+phone ).increment(1);if(count==1){//设置 30 分钟过期stringRedisTemplate.expire(AppConstants.REDIS_SMS_USER_PREFIX+phone, AppConstants.REDIS_SMS_USER_EXPIRE , TimeUnit.SECONDS);}if(count > 5){log.info("验证码发送频繁,超过了限定的次数");return AjaxResult.error("验证码发送频繁,超过了限定的次数");}//生成随机验证码String code=getNonce_str();//发送短信/* String sms= SendSMS.sendSms(apikey,send,phone,code);//查看是否发送成功JSONObject json=JSONObject.parseObject(sms);String success=json.getString("status");if (!success.equals("success")){//发送失败,次数减回来 -1 表示stringRedisTemplate.boundValueOps(AppConstants.REDIS_SMS_USER_PREFIX+phone ).increment(-1);return AjaxResult.error("短信发送失败");}*///发送成功,放入redisstringRedisTemplate.opsForValue().set(AppConstants.REDIS_SMS_PREFIX+phone, code ,AppConstants.REDIS_SMS_EXPIRE,TimeUnit.SECONDS);log.info("验证码发送成功");return AjaxResult.success("操作成功",code);}catch (Exception e){log.info("短信验证码发送失败"+ ExceptionUtils.getStackTrace(e));return AjaxResult.error("短信验证码发送失败");}}@PostMapping("sys/checkSmsCode")public AjaxResult checkSmsCode(String phone,String code){try {log.info("开始验证手机号验证码:"+phone+","+code);String rediscode=stringRedisTemplate.opsForValue().get(AppConstants.REDIS_SMS_PREFIX+phone);if (rediscode ==null || !rediscode.equals(code)){return AjaxResult.error("验证码错误");}log.info("验证码验证成功");return AjaxResult.success();}catch (Exception e){log.info("短信验证码验证失败"+ ExceptionUtils.getStackTrace(e));return AjaxResult.error("短信验证码验证失败");}}/*** 获取长度为 4 的随机数字* @return 随机数字* @date*/public static String getNonce_str() {// 如果需要4位,那 new char[4] 即可,其他位数同理可得char[] nonceChars = new char[4];for (int index = 0; index < nonceChars.length; ++index) {nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));}return new String(nonceChars);}}

AppConstants 类是放缓存 key 的前缀和过期时间 ,大家可以自己定义,顺便把类也贴一下

public class AppConstants {public static final String REDIS_KEY_PREFIX = "botao:"; // redis缓存前缀/** redis session 前缀*/public static final String REDIS_SESSION_PREFIX = "botao:session:";/** redis缓存 session失效时间 秒*/public static final int REDIS_SESSION_EXPIRE = 60*60*24*30;/** redis token 前缀*/public static final String REDIS_TOKEN_PREFIX = "botao:token:";/** redis缓存 token失效时间 秒*/public static final int REDIS_TOKEN_EXPIRE = 60*60*24*30;/** redis缓存 验证码 失效时间 秒*/public static final int REDIS_SMS_EXPIRE = 60*5;/** redis缓存 验证码 失效时间 秒*/public static final int REDIS_SMS_USER_EXPIRE = 60*30;/** redis sms 前缀*/public static final String REDIS_SMS_PREFIX = "botao:sms:";/** redis sms 前缀*/public static final String REDIS_SMS_USER_PREFIX = "botao:count:sms:";}

上面设置的是半小时内,发送 5 次 ,经过测试,可以对单位时间内发送次数做限制

使用Springboot StringRedisTemplate 在单位时间内对发送手机号验证码次数做限制 半小时最多发送5次验证码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。