Django 用戶的修改密碼接口


實現修改密碼接口

請求方式: POST

修改請求參數 :      /change_pwd/

業務處理流程

驗證手機號是否注冊    (格式, ajax請求檢查)

原密碼是否正確   (格式,null, 數據庫檢查)

新密碼是否正確   (格式, null, 存數據庫)

參數 是否前端傳入 描述 類型
mobile 用戶輸入的手機號 字符串
old_password 用戶輸入要修改的密碼 字符串
new_password 用戶輸入的新密碼 字符串
sms_code 用戶輸入的短信驗證碼 字符串

 

 

 

 

 

注:由於是post請求,在向后端發起請求時,需要附帶csrf token

 

前端代碼  (畢竟是前端發送ajax請求的)

 

$(function () {
    let $mobile = $('#mobile');
    let $smsCodeBtn = $('.form-item .sms-captcha');  // 獲取短信驗證碼按鈕元素,需要定義一個id為input_smscode
    let $submit = $('.form-contain');


    // 手機號檢測
    $mobile.blur(function () {
    fn_check_mobile();
    });

    // 短信驗證碼發送
    $smsCodeBtn.click(function () {




      // 判斷手機號是否輸入
    if (fn_check_mobile() !== "success") {
        return
    }
    let SdataParams = {
      "mobile": $mobile.val(),   // 獲取用戶輸入的手機號
    };

    $.ajax({
        //請求地址
        url : "/change_pwd/sms_code/",
        //請求方式
        type: "POST",
        data: JSON.stringify(SdataParams),
        contentType: "application/json; charset=utf-8",
        dataType : "json",
        async: false,
    })
        .done(function (res) {
           if (res.errno === "0") {
          // 倒計時60秒,60秒后允許用戶再次點擊發送短信驗證碼的按鈕
           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 soldPassword = $("input[name=old_password]").val();
        let snewPassword = $("input[name=new_password]").val();
        let sSmsCode = $("input[name=sms_captcha]").val();

        if (fn_check_mobile() !== "success") {
            return
        }

        // 判斷用戶輸入的密碼是否為空
        if ((!soldPassword) || (!snewPassword)) {
          message.showError('密碼或確認密碼不能為空');
          return
        }

        // 判斷用戶輸入的密碼和確認密碼長度是否為6-20位
        if (!(/^[0-9A-Za-z]{6,20}$/).test(snewPassword)) {
          message.showError('新密碼的長度需在6~20位以內');
          return
        }
        // 判斷用戶輸入的密碼和確認密碼長度是否為6-20位
        if (!(/^[0-9A-Za-z]{6,20}$/).test(soldPassword)) {
          message.showError('原密碼的長度需在6~20位以內');
          return
        }

        // 密碼不能一樣
        if (soldPassword == snewPassword) {
          message.showError('原密碼和新密碼一致,請重新檢查並輸入');
          return
        }

        //短信驗證碼格式
        if (!(/^\d{6}$/).test(sSmsCode)) {
          message.showError('短信驗證碼格式不正確,必須為6位數字!');
          return
        }

        //發起POST請求
        let SdataParams = {
          "mobile": sMobile,
          "old_password": soldPassword,
          "new_password": snewPassword,
          "sms_code": sSmsCode,
        };

        $.ajax({
            url: "/change_pwd/",

            type: "POST",

            headers: {
              "X-CSRFToken": getCookie("csrf_token")
            },
            data: JSON.stringify(SdataParams),

            contentType: "application/json; charset=utf-8",

            dataType: "json",

        })
          .done(function (res) {
        if (res.errno === "0") {
          // 注冊成功
          message.showSuccess('恭喜你, 修改成功!');
          setTimeout(function () {
            // 注冊成功之后重定向到主頁
            window.location.href = document.referrer;
          }, 1000)
        } else {
          // 注冊失敗,打印錯誤信息
          message.showError(res.errmsg);
        }
      })
          .fail(function(){
        message.showError('服務器超時,請重試!');
      });








    });

    // 檢查手機號是否被注冊
    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: 'change_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 () {
        message.showError('服務器超時,請重試!');
        sReturnValue = ""
      });
    return sReturnValue

  }
    
    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;
  }
});
View Code

 

 

后端

class ChangePwdMobile(View):
    """
    Check whether the user exists in ChangePwd page
    GET mobiles/(?P<mobile>1[3-9]\d{9})/
    """

    def get(self, request, mobile):
        data = {
            'mobile': mobile,
            'count': Users.objects.filter(mobile=mobile).count()
        }
        return to_json_data(data=data)
驗證手機號是否注冊

 

class ChangePwdSmsCode(View):
    """
    send sms_code in changePwd
    """
    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='參數錯誤')

        # 發送短信頻繁
        try:
            con_redis = get_redis_connection(alias='changePwd_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='changePwd_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 ChangePwd(View):
    """
    get : change_pwd  page
    post: submit
    """
    def get(self, request):
        return render(request, 'users/change_pwd.html')

    def post(self, request):
        json_str = request.body
        if not json_str:
            return to_json_data(errno=Code.PARAMERR, errmsg='參數為空')
        dict_data = json.loads(json_str.decode('utf-8'))
        mobile = dict_data.get('mobile')
        old_password = dict_data.get('old_password')
        new_password = dict_data.get('new_password')
        sms_code = dict_data.get('sms_code')
        # 是否為空
        if not all([mobile, old_password, new_password, 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}$', old_password):
            return HttpResponseForbidden('新密碼格式不正確')
        # 新密碼格式
        if not re.match('^[0-9A-Za-z]{6,20}$', new_password):
            return HttpResponseForbidden('新密碼格式不正確')
        # 原密碼和新密碼
        if new_password == old_password:
            return HttpResponseForbidden('原密碼和新密碼相同,請重試')
        # 驗證碼格式是否正確
        if not sms_code.isnumeric():
            return ("請重新檢查你的驗證碼是否正確    Forms ")

        # 拿到當前對象user
        user = Users.objects.get(mobile=mobile)
        if user:
            if check_password(old_password, user.password):
                user.set_password(new_password)
                user.save()
                return to_json_data(errno=Code.OK, errmsg='恭喜你修改成功')
            else:
                return to_json_data(errno=Code.PARAMERR, errmsg='原密碼錯誤')
        else:
            return to_json_data(errno=Code.PARAMERR, errmsg='不存在當前用戶')
修改密碼接口

 

 

URL配置

path('change_pwd/', views.ChangePwd.as_view(), name='change_pwd'),

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM