django 的忘记密码接口
Posted jackson669
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django 的忘记密码接口相关的知识,希望对你有一定的参考价值。
实现修改密码接口
请求方式: POST
修改请求参数 : /forget_pwd/
业务处理流程:
验证手机号是否注册 (格式, ajax请求检查)
发送验证码
新密码是否正确 (格式, null, 存数据库)
参数 | 是否前端传入 | 描述 | 类型 |
mobile | 是 | 用户输入的手机号 | 字符串 |
new_password | 是 | 用户输入的新密码 | 字符串 |
sms_code | 是 | 用户输入的短信验证码 | 字符串 |
注:由于是post请求,在向后端发起请求时,需要附带csrf token
前端代码
$(function () { let $mobile = $(‘#mobile‘); let $smsCodeBtn = $(‘.form-item .sms-captcha‘); let $submit = $(‘.form-contain‘); // 检查手机号是否被注册 function fn_check_mobile() { let sMobile = $mobile.val(); let sReturnValue = ""; if (sMobile === "") { message.showError(‘手机号不能为空‘); return } if (!(/^1[345789]d{9}$/).test(sMobile)){ message.showError(‘手机格式不正确,请重新输入!‘); return } $.ajax({ url: ‘forget_pwd/mobiles/‘ + sMobile + ‘/‘, type: ‘GET‘, dataType: "json", async: false, }) .done(function (res) { if (res.data.count == 0){ message.showError(res.data.mobile + ‘尚未注册,请重新输入‘); sReturnValue = "" }else { message.showSuccess(res.data.mobile + ‘号码正确‘); sReturnValue = "success" } }) .fail(function (res) { message.showError(‘服务器超时,请重试‘); sReturnValue = "" }); return sReturnValue } // 手机号验证是否存在 $mobile.blur(function () { fn_check_mobile(); }); // 短信验证码 $smsCodeBtn.click(function () { if (fn_check_mobile() !== "success"){ message.showError(‘手机账户验证不成功‘); return } let SdataParams = { "mobile": $mobile.val(), }; $.ajax({ url: ‘/forget_pwd/sms_code/‘, type : ‘POST‘, dataType : ‘json‘, data: JSON.stringify(SdataParams), contentType: ‘application/json; charset=utf-8‘, async: false, }) .done(function (res) { if (res.errno === "0"){ message.showSuccess(‘短信验证码发送成功!‘); let num = 60; // 计时器 let t = setInterval(function () { if (num === 1){ // 如果计时器到最后, 清除计时器对象 clearInterval(t); // 将点击获取验证码的按钮展示的文本恢复成原始文本 $smsCodeBtn.html("获取验证码"); }else { num -= 1; // 展示倒计时信息 $smsCodeBtn.html(num + ‘秒后重试‘) } }, 1000); }else { message.showError(res.errmsg); } }) .fail(function () { message.showError(‘服务器超时,请重试‘) }); }); // 确认修改 $submit.submit(function (e) { e.preventDefault(); //获取用户输入的内容 let sMobile = $mobile.val(); let snewPassword = $("input[name=new_password]").val(); let sSmsCode = $("input[name=sms_captcha]").val(); if(fn_check_mobile() !== "success"){ return } //判断用户输入的密码是否为空 if (!(snewPassword)) { message.showError("新密码不能为空"); return } // 密码不能一样 if (!(/^[0-9A-Za-z]{6,20}$/).test(snewPassword)) { message.showError(‘新密码的长度需在6~20位以内‘); return } //短信验证码格式 if (!(/^d{6}$/).test(sSmsCode)) { message.showError(‘短信验证码格式不正确,必须为6位数字!‘); return } // 发起POST请求 let SdataParams = { "mobile" : sMobile, "sms_code" : sSmsCode, "new_password": snewPassword, }; $.ajax({ url: ‘/forget_pwd/‘, type : ‘POST‘, dataType: ‘json‘, contentType: ‘application/json; charset=utf-8‘, headers: { "X-CSRFToken": getCookie("csrf_token") }, data: JSON.stringify(SdataParams), }) .done(function (res) { if (res.errno === "0"){ //注册成功 message.showSuccess(‘恭喜你,修改成功‘); setTimeout(function () { //注册成功之后自动重定向到主页 window.location.href = document.referrer; }, 1000) }else { //注册失败,打印错误信息 message.showError(‘服务超时,请重试‘); } }); function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== ‘‘) { let cookies = document.cookie.split(‘;‘); for (let i = 0; i < cookies.length; i++) { let cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + ‘=‘)) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } }); });
后端代码
class ForgetPwdMobile(View): def get(self, request, mobile): data = { ‘mobile‘: mobile, ‘count‘: Users.objects.filter(mobile=mobile).count() } return to_json_data(data=data) def post(self, request): pass class ForgetPwdSmsCode(View): def post(self, request): try: json_data = request.body if not json_data: return to_json_data(errno=Code.PARAMERR, errmsg="参数为空,请重新输入") dict_data = json.loads(json_data.decode(‘utf8‘)) except Exception as e: logger.info(‘错误信息: {}‘.format(e)) return to_json_data(errno=Code.UNKOWNERR, errmsg="未知错误") mobile = dict_data.get(‘mobile‘) if not mobile: return to_json_data(errno=Code.PARAMERR, errmsg=‘参数错误‘) if not re.match(‘^1[345789]d{9}$‘, mobile): return to_json_data(errno=Code.PARAMERR, errmsg=‘手机号错误‘) # 发送短信频繁 try: con_redis = get_redis_connection(alias=‘forgetPwd_codes‘) except Exception as e: # 日志器 return to_json_data(Code.UNKOWNERR, errmsg=‘未知错误‘) send_flag = con_redis.get(‘sms_flag_{}‘.format(mobile)) if send_flag: return to_json_data(errno=Code.DATAEXIST, errmsg=‘发送短信频繁‘) sms_num = ‘%06d‘ % random.randint(0, 999999) print(sms_num) # 保存 redis_con = get_redis_connection(alias=‘forgetPwd_codes‘) # 短信验证码 写key sms_text = "sms_{}".format(mobile).encode(‘utf-8‘) # 过期时间 sms_flag = "sms_flag_{}".format(mobile).encode(‘utf-8‘) p2 = redis_con.pipeline() # 保存验证码 try: p2.setex(sms_text, constant.SMS_CODE_REDIS_EXPIRES, sms_num) p2.setex(sms_flag, constant.SEND_SMS_CODE_INTERVAL, 1) p2.execute() except Exception as e: logger.debug("redis 执行出现异常 {}".format(e)) return to_json_data(errno=Code.UNKOWNERR, errmsg=error_map[Code.UNKOWNERR]) # 发送验证码 logging.info("发送验证码短信【成功】[mobile:{}, sms_code:{}]".format(mobile, sms_num)) return to_json_data(errno=Code.OK, errmsg="短信验证码发送成功") class ForgetPwd(View): def get(self, request): return render(request, ‘users/forget_pwd.html‘) def post(self, request): try: json_data = request.body if not json_data: return to_json_data(errno=Code.PARAMERR, errmsg="参数错误,请检查") dict_data = json.loads(json_data.decode(‘utf-8‘)) except Exception as e: logger.info(‘错误信息 {}‘.format(e)) return to_json_data(errno=Code.UNKOWNERR, errmsg=‘未知错误‘) new_password = dict_data.get(‘new_password‘) mobile = dict_data.get(‘mobile‘) sms_code = dict_data.get(‘sms_code‘) if not all([new_password, mobile, sms_code]): return HttpResponseForbidden(‘参数为空,请检查‘) # 手机格式 if not re.match(‘^1[3-9]d{9}$‘, mobile): return HttpResponseForbidden(‘手机号码格式输入错误‘) # 新密码格式 if not re.match(‘^[0-9A-Za-z]{6,20}$‘, new_password): return HttpResponseForbidden(‘新密码格式不正确‘) # 验证码 if not re.match(‘^d{6}$‘, sms_code): return HttpResponseForbidden(‘验证码错误,请重新输入‘) # 验证码校验 redis_con = get_redis_connection(‘forgetPwd_codes‘) sms_code_server = redis_con.get(‘sms_‘ + mobile) # 判断是否过期 if sms_code_server is None: return to_json_data(errno=Code.PARAMERR, errmsg=‘验证码过期‘) # 用完就删除 redis_con.delete(‘sms_flag_{}‘.format(mobile)) redis_con.delete(‘sms_{}‘.format(mobile)) # 判断是否正确 if sms_code != sms_code_server.decode(): return HttpResponseForbidden(‘验证码错误!!!!‘) user = Users.objects.get(mobile=mobile) if user: user.set_password(new_password) user.save() return to_json_data(errno=Code.OK, errmsg=‘恭喜你修改成功‘) else: return to_json_data(errno=Code.PARAMERR, errmsg=‘不存在当前用户‘)
URL
path(‘forget_pwd/‘, views.ForgetPwd.as_view(), name=‘forget_pwd‘), re_path(‘forget_pwd/mobiles/(?P<mobile>1[3-9]d{9})/‘, views.ForgetPwdMobile.as_view(), name=‘change_pwd_mobile‘), path(‘forget_pwd/sms_code/‘, views.ForgetPwdSmsCode.as_view(), name=‘forget_pwd_sms_code‘),
以上是关于django 的忘记密码接口的主要内容,如果未能解决你的问题,请参考以下文章