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;
  }
    });
    
});
JS代码

 

后端代码

技术图片
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 的忘记密码接口的主要内容,如果未能解决你的问题,请参考以下文章

忘记了 django 和 graphql 的密码?

Django中忘记密码的实现

在django中忘记密码

如何覆盖默认的 django 忘记密码模板?

向 Django 2.1 管理站点添加忘记密码功能

Django忘记密码电子邮件系统期间的NoReverseMatch错误