如何防止刷短信验证码?

问题:在前端使用云服务实现发送短信业务时,若未启用验证码防刷机制,会导致他人恶意或者无意刷新验证码,导致服务器压力变大,以及短信服务超额。

解决方案:采用redis存储短信验证码,在前端以及后端同时采用防刷机制,双重防刷,步骤如下;

前端:使用js代码检测上次点击的时间多久(如果刷新页面,会被重新清空,需要后端服务器读取redis中的数据确定发送时间)

<a id="sendCode">发送验证码</a>
//全局定义一个时间,这里设置成60s
var num = 60;
function timeoutChangeStyle(){
        //使用jQuery获取元素属性,设置成不可点击
		$("#sendCode").attr("class","disabled")
		if(num>0){
			var str = num+"s 后再次发送"
			$("#sendCode").text(str)
            //设置1s改变一次样式
			setTimeout("timeoutChangeStyle()",1000)	
		}else{
		    num=60
		    $("#sendCode").text("发送验证码")
		    $("#sendCode").attr("class","")
		}
		num--;
}

后端:使用阿里云短信服务,操作api获取到验证码,在redis存储验证码时,加入前缀,来辨别验证码的来源,同时将验证码与记录时间合并,以“_”隔开,用于检测验证码是否超过60s。

具体步骤如下:

1)存储时,使用key-value键值对存储,这里对key与value分别做处理,使其具有防刷的特征;

2)存储key时,将手机号作为key,同时加上常量前缀,作为命名空间,格式:常量+手机号

3)存储value时,将验证码与存储的时间节点同时存储(这里用UUID模仿阿里云服务的验证码),然后以“_”符号隔开,格式:验证码 + “_” + 时间节点

    @ResponseBody
    @GetMapping("/sms/sendcode")
    public R sendCode(@RequestParam("phone") String phone){
        //接口防刷
        String redisCode = redisTemplate.opsForValue().get("LOGINCONSTANT" + phone);
        if(!StringUtils.isEmpty(redisCode)){
            long l = Long.parseLong(redisCode.split("_")[1]);
            if(System.currentTimeMillis()-l < 60000){
                return R.error("10002", "短信验证码频率太高,稍后再试");
            }
        }
        //用UUID模仿云服务传来的验证码
        String code = UUID.randomUUID().toString().substring(0, 5);
        //格式:验证码 + “_” + 时间节点
        String codeWithTime = code + "_" + System.currentTimeMillis();
        redisTemplate.opsForValue().set("LOGINCONSTANT" + phone,codeRedis,10, TimeUnit.MINUTES);
        return R.ok();
    }

如何检测验证码是否有60s?

存储在redis的数据里的结构是 常量+手机号(key)-验证码 + “_” + 时间节点(value) ,当前端点击发送验证码按钮时:

1)先从redis中检测该手机号是否存储相应的验证码,若不存在,就按上面格式存储一份验证码。

2)若存在,按照存储的key取出相应的值,用split方法将验证码与时间戳分隔开,将存储的时间戳与当前时间做减法,若未超过60s,前端返回相应提示信息,提醒用户时间未到。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值