一、后端设置
class SmsCodeView(View):
def get(self, request, mobile):
# 获取redis连接对象,存储短信验证码
try:
redis_conn = get_redis_connection('verify_code')
except DatabaseError as e:
return http.JsonResponse({
'errmsg': '获取验证码失败'
})
# 获取发送标志
send_flag = redis_conn.get('send_flag_%s' % mobile)
# 如果发送标志存在,说明用户在60秒内多次获取验证码
if send_flag:
return http.JsonResponse({
'errmsg': '发送短信验证码过于频繁'
})
# 生成随机6为验证码
sms_code = '%06d' % random.randint(0, 999999)
# 存储随机验证码(五分钟的有效期)
redis_conn.setex('sms_code_%s' % mobile, 300, sms_code)
# 设置发送标志
redis_conn.setex('send_flag_%s' % mobile, 60, 1)
# 初始化SmsSDK
send_code = SmsSDK(accId=utils.ACCID, accToken=utils.ACCTOKEN, appId=utils.APPID)
# 发送短信验证码(这里的发送验证码是一个耗时操作)
send_code.sendMessage(tid='1', mobile=mobile, datas=(sms_code, 5))
# 返回响应
response = http.JsonResponse({
'errmsg': 'ok'
})
response.headers['Access-Contro1-Allow-origin'] = '*'
return response
关键代码:
1、 redis_conn.setex('send_flag_%s' % mobile, 60, 1):
在获取请求后,对当前手机号发送短信验证码后,为当前手机号在redis中设置一个send_flag_‘mobile’的键,有效期为60秒,值为1
2、
send_flag = redis_conn.get('send_flag_%s' % mobile) # 如果发送标志存在,说明用户在60秒内多次获取验证码 if send_flag: return http.JsonResponse({ 'errmsg': '发送短信验证码过于频繁' })一开始,后端接受请求后便获取redis连接对象,获取键send_flag_‘mobile’,如果用户在60内又发送了一次获取短信验证码的请求,则表示该键在redis中存在,则此时返回错误信息 ,这样可以有效的避免,不良用户绕过前端频繁的向后端发送验证码请求,否则键不存在,正常发送短信验证码
二、前端设置
<template>
<div>
<div>
<label for="">手机号: </label>
<input type="text" value="请输入手机号" v-model="mobile">
</div>
<div>
<label for="">验证码: </label>
<input type="text" v-model="sms_code"><button @click="send_code">{{getsmscode}}</button>
</div>
<div>
<button @click="check_sms_code">验证</button>
<span v-show="show_errmsg_status">{{show_errmsg}}</span><br/>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
show_errmsg_status:false, //是否显示错误提示信息
show_errmsg:'',//显示错误提示信息
getsmscode:'点击获取验证码',
mobile:'',//手机号
sms_code:'',//验证码
url :'/api/auth/sms_code/'
}
},
methods: {
send_code() {//发送验证码请求
axios.get(this.url+this.mobile+'/',{
responseType: 'json',
})
.then(res=>{
if(res.data.errmsg='ok'){
//设置倒计时时间
var num=60;
//设置定时器,对发送短信验证码按钮进行倒计时
var t=setInterval(()=>{
if (num===1){
clearInterval(t);//清空
this.getsmscode='点击发送验证码';
this.show_errmsg_status=false;
}
else {
this.getsmscode=num+'秒';
num-=1;
}
},1000,60);
}
else{
this.show_errmsg_status=true;//显示错误信息
this.show_errmsg=res.data.errmsg;
}
})
.catch(err=>{
console.log(err.data);
})
},
check_sms_code(){//验证码验证码请求
axios.post(this.url+ this.mobile+'/',{
sms_code:this.sms_code//携带验证码参数
})
.then(res=>{
if(res.data.errmsg='ok'){
this.show_errmsg_status=false;
alert('验证成功')//成功即弹框
}
else{
this.show_errmsg_status=true;//显示错误信息
this.show_errmsg=res.data.errmsg;
}
})
.catch(err=>{
console.log(err.data)
})
}
},
}
</script>
<style lang="scss" scoped>
</style>
关键代码:添加定时器,实现60秒,倒计时操作
if(res.data.errmsg='ok'){ //设置倒计时时间 var num=60; //设置定时器,对发送短信验证码按钮进行倒计时 var t=setInterval(()=>{ if (num===1){ clearInterval(t);//清空 this.getsmscode='点击发送验证码'; this.show_errmsg_status=false; } else { this.getsmscode=num+'秒'; num-=1; } },1000,60); } else{ this.show_errmsg_status=true;//显示错误信息 this.show_errmsg=res.data.errmsg; }
三、测试: