Django实现短信验证登录(使用第三方平台短信发送服务)
以下代码使用螺丝帽短信接口(https://luosimao.com/)
- 前端功能:
- 点击按钮Ajax调用发送验证码功能
- 输完验证码后Ajax调用验证功能
- 后端功能:
- 功能1:发送验证码功能
- 功能2:验证码检查
- 后台核心逻辑(不需要手写)
- 功能3:发短信
- 功能4:生成短信验证码(随机生成6位数字)
- 集成Redis
- 使用Redis代替session缓存, 存储数据!
因为我们短信验证码生命周期控制的非常严格!而且数据用完后不需要存储. 所以建议直接把数据存储在缓存/内存中! - Redis集成到Django中!
以下代码为Django2.2版本,默认已经创建应用并完成了需要的配置,如果不知道配置的请参考(https://www.jianshu.com/p/791944e99bf8)
流程:
- 获取手机号---->生成6位验证码–>缓存验证码到Redis—>发短信–>返回状态
-
在应用下新建一个文件,定义一个函数生成指定长度的数字
def gen_mobile_code(length=6):
all_charts = ‘0123456789’
return ‘’.join(random.choices(all_charts,k = length)) -
在view.py中定义视图函数
TEL_PATTERN = re.compile(r’1[3-9]\d{9}’) # 视情况而定的号码格式
def get_mobile_code(request):
‘’‘发送短信验证码’’’
tel = request.GET.get(‘tel’) # 获取前端输入的手机号
if TEL_PATTERN.fullmatch(tel): # 判断电话号码是否合法
if caches[‘default’].get(f’voteapp:polls:block:{tel}’): # 获取缓存中是否有保存的电话号码
data = {‘code’: 2004, ‘msg’: ‘请不要在60秒以内重复发送短信验证码!’}
else:
code = gen_mobile_code() #随机生成指定位数的数字
result = send_mobile_code(tel, code) # 调用三方平台的接口
if result[‘error’] == 0:
caches[‘default’].set(f’voteapp:polls:block:{tel}’, code, 60) # 设置60秒内勿重复发短信
caches[‘default’].set(f’voteapp:polls:valid:{tel}’, code, 600) # 缓存中保存发送的验证码并设置短信的过期时间
data = {‘code’:2000, ‘msg’:‘成功!’}
else:
data = {‘code’:2001, ‘msg’:‘失败!’}else: data = {'code': 2003, 'msg':'手机号码无效!'} return JsonResponse(data)
-
三方平台的短信接口(不同平台请参考官方文档)
def send_mobile_code(tel,code):resp = requests.post("http://sms-api.luosimao.com/v1/send.json", auth=("api", "key-你的身份验证码,注册可得"), data={ "mobile": tel, "message": f'小主,这是你的验证码哟:{code},千万不要让人知道哦【铁壳测试】' }, # timeout=3, verify=False ) result = json.loads(resp.text) print(code) print(result) return result
-
前端代码为
<script > $('#sendBtn').on('click',(evt) => { let tel = $(evt.target).prev().val().trim() let pattern = /^1[3-9]\d{9}$/ if (pattern.test=tel){ fetch('/polls/mcode/?tel='+tel).then(resp => resp.json()).then(json =>{ $(evt.target).prop('disabled',true) if(json.code === 2000){ countdown = 60 # 设置定时器 setTimeout(delaySend,1000) }else { alert(json.msg) } }) }else { alert('无效的手机号码') } }) </script>
-
后端验证代码为:
def register(request):
‘’‘注册页面’’’
if request.method ==‘GET’:
return render(request, ‘register.html’) # 返回登录页面
elif request.method == ‘POST’:
context = {
‘hint’: ‘’ ,
‘code’:200,
}# 获取前端输入的验证码 mobilecode = str(request.POST.get('mobilecode')) # 获取缓存中保存的验证码进行对比 mob = str(caches['default'].get(f'voteapp:polls:valid:{tel}')) tel = request.POST.get('tel') username = request.POST.get('username') password = make_sha256_digest(request.POST.get('password')) if mob == mobilecode: print(password) user = User() user.username = username user.password = password user.tel = tel user.save() context['hint'] = '注册成功,请返回登录' else: context['hint'] = '验证码输入不正确。请重新输入' context['code'] = 201 # return JsonResponse(context) return render(request, 'register.html',context=context)
注意:整体项目请参考(https://gitee.com/anemo/qianFengvote)