Redis实现短信验证码

利用Redis实现存储短信验证码

  • 要求需要限制短信在1分钟之内不能再次发送
  • 要求短信一天之内的发送的短信条数限制10条

思路

  • 需要两个缓存
  • key名称为phone-code,缓存1分钟
  • key名称为phone-count,缓存1天,每成功发送一条+1
  • 流程:
  1. 判断phone-code是否存在,存在直接报错,“短信发送频繁,请1分钟之后再试”
  2. 判断phone-count是否存在,存在则继续检测是否等于10,存在且等于10报错,“您今天的发送次数超过10次”
  3. 发送短信
  4. 写入phone-code,有效期1分钟
  5. 写入phone-count,有效期当天23:59:59的时间戳-当前时间戳

实现

短信接口
@RequestMapping(value = "phoneMsg")
public  Object sendXCXDuanxin(HttpServletRequest request,@RequestParam Map  map) throws ParseException {

//判断参数phone
String phone = map.containsKey("phone") ? String.valueOf(map.get("phone")) :  null;

//定义Redis变量名
String Count="phone-count:"+phone;
String Code="phone-code:"+phone;

//判断对应的key是否存在
//存在则获取对应的value,否则为“”
String isRedis =redisTemplate.hasKey(Code)?String.valueOf(redisTemplate.opsForValue().get(Code)):"";
//判断是否不为“”
if (!"".equals(isRedis)){
   return Results.failure("短信发送频繁,请一分钟后再试!");
}

if ("10".equals(redisTemplate.opsForValue().get(DuanxinCount))){
   return Results.failure("该手机号收发短信已达上限");
}

//存入缓存
//设置有效时长为1分钟
redisTemplate.opsForValue().set(Code,verifyCode,1L,TimeUnit.MINUTES);

//判断
if (redisTemplate.opsForValue().get(Count)==null){   redisTemplate.opsForValue().set(Count,"1",getEndTime(),TimeUnit.MILLISECONDS);
}else {
   String value = redisTemplate.opsForValue().get(Count).toString();
   int times = Integer.parseInt(value) + 1;
   String timesStr = String.valueOf(times);
   //有效期截止到当天晚上
   redisTemplate.opsForValue().set(Count,timesStr,getEndTime(),TimeUnit.MILLISECONDS);
}
}
//获取当前时间到今天结束时间所剩余的毫秒数:
public static long getEndTime() {
   //获取当前时间的毫秒数
   long time = new java.util.Date().getTime();
   //获取到今天结束的毫秒数
   Calendar todayEnd = Calendar.getInstance();
   todayEnd.set(Calendar.HOUR_OF_DAY, 23); // Calendar.HOUR 12小时制。HOUR_OF_DAY 24小时制
   todayEnd.set(Calendar.MINUTE, 59);
   todayEnd.set(Calendar.SECOND, 59);
   todayEnd.set(Calendar.MILLISECOND, 999);
   long endTime = todayEnd.getTimeInMillis();
   //这里endTime-time获取的是到23:59:59:999的毫秒数。再加1才是到24点整的毫秒数
   return endTime-time+1;
}
实现2.0
//定义redis key的name
String DuanxinCountByDay="phone-send-day:"+phone;

//判断是否有对应的key
Integer counts=redisTemplate.hasKey(DuanxinCountByDay)?Integer.valueOf(redisTemplate.opsForValue.get(DuanxinCountByDay).toString()):null;


if(counts==null){
    //今天第一次验证,故之前缓存中无该键
    //距离今天结束剩下多少毫秒
    Calendar calendar =Calendar.getInstance();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    calendar.set(Calendar.MILLISECOND,0);
    calendar.set(Calendar.SECOND,0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.add(Calendar.DAY_OF_MONTH, 1);

    long expire=(calendar.getTimeInMillis()-System.currentTimeMillis())/1000;

redisTemplate.opsForValue().set(DuanxinCountByDay,1,expire,TimeUnit.SECONDS);
}else if(counts < 3){
    //没有超过限制次数
    redisTemplate.opsForValue().increment(DuanxinCountByDay,1);
}else{
    //超过限制次数,不生成验证码,直接返回
    return Results.failure("已超过当天短信发送次数");
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redis可以用来实现短信验证码功能,具体步骤如下: 1. 生成验证码:使用随机数生成器生成一个6位数字的验证码,并将其存储到Redis中,以手机号作为key,验证码作为value,同时设置过期时间为5分钟。 2. 发送验证码:将验证码发送到用户手机上,可以使用短信平台或者第三方SDK来实现。 3. 验证验证码:用户输入验证码后,从Redis中读取对应手机号的验证码,与用户输入的验证码进行比对,如果一致则验证通过,否则验证失败。 以下是使用Redis实现短信验证码的代码示例(使用Python语言): ``` import redis import random import time # 连接Redis r = redis.Redis(host='localhost', port=6379, db=0) # 生成验证码 def generate_verification_code(phone): verification_code = random.randint(100000, 999999) r.set(phone, verification_code, ex=300) # 设置过期时间为5分钟 return verification_code # 验证验证码 def verify_verification_code(phone, verification_code): stored_code = r.get(phone) if stored_code is None: return False if int(stored_code) != verification_code: return False r.delete(phone) # 验证通过后删除验证码 return True # 示例代码 phone = '13812345678' code = generate_verification_code(phone) print(code) time.sleep(2) # 模拟发送验证码到用户手机上的过程 result = verify_verification_code(phone, code) print(result) ``` 需要注意的是,由于Redis是内存数据库,如果服务器重启或者Redis进程被杀死,存储在Redis中的数据会丢失,因此需要根据实际情况进行合理的持久化和备份。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值