注册时短信验证后端逻辑
class CheckSMScodeView(View):
def get(self,request,phone):
'''
用户注册时短信验证码的校验功能
:param request:
:param phone:
:return:
'''
smscode_client=request.GET.get('smscode','')
if not all([phone,smscode_client]):
return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})
redis_conn=django_redis.get_redis_connection('verify_code')
smscode_server=redis_conn.get('sms_%s'%phone)
if smscode_server is None:
return JsonResponse({'code':'4002','errormsg':'短信验证码失效'})
smscode_server=smscode_server.decode('utf-8')
if smscode_client != smscode_server:
return JsonResponse({'code':'4003','errormsg':'短信验证码不一致'})
return JsonResponse({'code':'200','errormsg':'ok'})
注册时短信验证前端逻辑
register.html
<p class="form-row form-row-wide">
<input style="width: 230px;" v-model="smscode" placeholder="短信验证码" @blur="check_smscode" name="msgcode" type="text" class="input-text" id="reg_mescode" >
<span class="error-tip" v-show="error_smscode">${error_smscode_msg}</span><a href="javascript:;" style="font-size: 16px;text-align: center;font-weight: normal;float: right" id="reg_mescode_btn" able="able" @click="send_smscode" >${smscode_btn}</a>
</p>
register.js
check_smscode:function(){
let reg = /^\d{6}$/;
if(!reg.test(this.smscode)){
this.error_smscode = true;
}else{
this.error_smscode = false;
}
if(!this.error_smscode){
axios.get('/check_smscode/'+this.phone+'/?smscode='+this.smscode,{
responseType:'json'
}).then(response=>{
let code = response.data.code;
if(code!='200'){
this.error_smscode = true;
this.error_smscode_msg = response.data.errormsg;
}else{
this.error_smscode = false;
}
})
}
},
存在的问题:
虽然我们在前端界?做了60秒倒计时功能。 但是恶意?户可以绕过前端界?向后端频繁请求短信验证码。
解决办法: 在后端也要限制?户请求短信验证码的频率。60秒内只允许?次请求短信验证码。 在Redis数据库中缓存?个数值,有效期设置为60秒。
避免频繁发送短信验证码
1、提取并校验is_send
redis_conn=django_redis.get_redis_connection('verify_code')
is_send=redis_conn.get('is_send_%s'%phone)
2、is_send 、smscode 存?redis数据库
redis_conn.setex('sms_%s'%phone,60,smscode_str)
redis_conn.setex('is_send_%s'%phone,60,1)
3、界?渲染频繁发送短信提示信息
{
if(response.data.code =='4001' ||response.data.code =='4002' ||response.data.code =='4003' ||response.data.code =='4004' ||response.data.code=='5001'){
this.error_smscode_msg = response.data.errormsg;
this.error_smscode = true;
}
this.send_flag = false;
this.generate_imgcode();
}
注册时短信验证后端总逻辑
class SMScodeView(View):
def get(self,request,phone):
'''
校验并删除图形验证码
发送短信验证码
:param request:
:param phone:
:return:
'''
imgcode_client=request.GET.get('imgcode','')
uuid=request.GET.get('uuid','')
uuid=uuid.strip('/')
if not all([phone,imgcode_client,uuid]):
return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})
redis_conn=django_redis.get_redis_connection('verify_code')
is_send=redis_conn.get('is_send_%s'%phone)
if is_send:
return JsonResponse({'code': '4004', 'errormsg': '发送短信验证码过于频繁'})
redis_conn=django_redis.get_redis_connection('verify_code')
imgcode_server=redis_conn.get('img_%s'%uuid)
if imgcode_server is None:
return JsonResponse({'code':'4002','errormsg':'图片验证码已过期'})
imgcode_server=imgcode_server.decode('utf-8')
print('redis的值为:',imgcode_server)
if imgcode_client.lower() != imgcode_server.lower():
return JsonResponse({'code':'4003','errormsg':'图片验证码不一致'})
try:
redis_conn.delete('img_%s'%uuid)
except Exception as e:
logger.error(e)
seed=string.digits
r=random.choices(seed,k=6)
smscode_str=''.join(r)
redis_conn.setex('sms_%s'%phone,60,smscode_str)
redis_conn.setex('is_send_%s'%phone,60,1)
ret={'code':2}
if ret.get('code')==2:
return JsonResponse({'code':200,'errormsg':'ok'})
return JsonResponse({'code':'5001','errormsg':'发送短信验证码错误'})
|