<del id="d4fwx"><form id="d4fwx"></form></del>
      <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

            <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
          • vue怎么實現(xiàn)短信驗證碼

            這篇文章主要講解了“vue怎么實現(xiàn)短信驗證碼”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“vue怎么實現(xiàn)短信驗證碼”吧!

            專注于為中小企業(yè)提供做網(wǎng)站、成都做網(wǎng)站服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)沽源免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

            一、需求

            1,需求

            我們在做網(wǎng)站開發(fā)時,登錄頁面很多情況下是可以用手機號接收短信驗證碼,然后實現(xiàn)登錄的,那我們今天就來做一做這一功能。

            vue怎么實現(xiàn)短信驗證碼

            偽代碼:

            進入登錄頁面,點擊短信登錄
            輸入手機號碼,點擊獲取驗證碼,后端在redis里保存驗證碼
            用戶把手機收到的驗證碼輸入,點擊登錄,會把手機號和驗證碼發(fā)往后端,然后進行驗證

            要想發(fā)送短信,讓用戶收到短信,我們的借助一個容聯(lián)云的接口,注冊一個賬號。

            vue怎么實現(xiàn)短信驗證碼

            使用時需要的一些參數(shù):

            vue怎么實現(xiàn)短信驗證碼

            下載sdk

            1.。。。。。。。

            vue怎么實現(xiàn)短信驗證碼

            2.。。。。。。

            vue怎么實現(xiàn)短信驗證碼

            3.。。。。。。。

            vue怎么實現(xiàn)短信驗證碼

            下載完成后,解壓。放入我們drf項目的apps里的libs里

            二、sdk參數(shù)配置  

            1,目錄結(jié)構(gòu)

            vue怎么實現(xiàn)短信驗證碼

            2,配置sms.py文件

            # -*- coding:utf-8 -*-
            
            from .CCPRestSDK import REST
            
            # 說明:主賬號,登陸云通訊網(wǎng)站后,可在"控制臺-應(yīng)用"中看到開發(fā)者主賬號ACCOUNT SID
            _accountSid = "xxxxxxxxxxxxx"
            # 8a216da863f8e6c20164139687e80c1b
            # 說明:主賬號Token,登陸云通訊網(wǎng)站后,可在控制臺-應(yīng)用中看到開發(fā)者主賬號AUTH TOKEN
            _accountToken = "xxxxxxxxxxxxx"
            # 6dd01b2b60104b3dbc88b2b74158bac6
            # 請使用管理控制臺首頁的APPID或自己創(chuàng)建應(yīng)用的APPID
            _appId = "8aaf0708697b6beb01699f3c645f1766"
            # 8a216da863f8e6c20164139688400c21
            # 說明:請求地址,生產(chǎn)環(huán)境配置成app.cloopen.com
            _serverIP = "sandboxapp.cloopen.com"
            
            # 說明:請求端口 ,生產(chǎn)環(huán)境為8883
            _serverPort = "8883"
            
            # 說明:REST API版本號保持不變
            _softVersion = "2013-12-26"
            
            #下面的內(nèi)容不用修改
            class CCP(object):
                """發(fā)送短信的輔助類"""
            
                def __new__(cls, *args, **kwargs):
                    # 判斷是否存在類屬性_instance,_instance是類CCP的唯一對象,即單例
                    if not hasattr(CCP, "_instance"):
                        cls._instance = super(CCP, cls).__new__(cls, *args, **kwargs)
                        cls._instance.rest = REST(_serverIP, _serverPort, _softVersion)
                        cls._instance.rest.setAccount(_accountSid, _accountToken)
                        cls._instance.rest.setAppId(_appId)
                    return cls._instance
            
                def send_template_sms(self, to, datas, temp_id):
                    """發(fā)送模板短信"""
                    # @param to 手機號碼
                    # @param datas 內(nèi)容數(shù)據(jù) 格式為數(shù)組 例如:{"12","34"},如不需替換請?zhí)?nbsp;""
                    # @param temp_id 模板Id
                    result = self.rest.sendTemplateSMS(to, datas, temp_id)
                    # 如果云通訊發(fā)送短信成功,返回的字典數(shù)據(jù)result中statuCode字段的值為"000000"
                    if result.get("statusCode") == "000000":
                        # 返回0 表示發(fā)送短信成功
                        return 0
                    else:
                        # 返回-1 表示發(fā)送失敗
                        return -1
            
            
            if __name__ == "__main__":
                ccp = CCP()
                # 注意: 測試的短信模板編號為1
                ccp.send_template_sms("15914397060", ["1234", 5], 1)

            三、代碼實現(xiàn)

            1,后端代碼

            views.py,這是獲取驗證碼請求的處理,也就是后端產(chǎn)生一個隨機碼,發(fā)送給手機用戶,然后把隨機碼存儲于redis中,然后給前端返回一個驗證碼發(fā)送成功的信號

            from .models import User
            from rest_framework import status
            from lufei_drf.libs.yuntongxun.sms import CCP
            from django_redis import get_redis_connection
            class SMSCodeAPIView(APIView):
                def get(self,request):
                    # 1. 通過查詢字符串獲取手機號碼
                    phone = request.query_params.get("phone")
                    ty=request.query_params.get("type")
                    # 2. 發(fā)送短信之前驗證碼驗證一下手機號碼
                    if ty=="register":
                        try:
                            User.objects.get(phone=phone)
                            return Response({"message": "當(dāng)前手機號已經(jīng)被注冊過"}, status=status.HTTP_400_BAD_REQUEST)
                        except:
                            pass
                    redis = get_redis_connection("sms_code")
                    if redis.get("times_%s" % phone):
                        return Response({"message": "當(dāng)前手機號已經(jīng)在一分鐘內(nèi)發(fā)送過短信"}, status=status.HTTP_400_BAD_REQUEST)
            
                    # 3. 使用手機號碼發(fā)送短信驗證碼
                    # 生成一個短信驗證碼
                    sms_code = "%04d" % random.randint(0, 9999)
                    ccp = CCP()
                    result = ccp.send_template_sms(phone,[sms_code,"5分鐘"],1)
            
                    if result == 0:
                        # 發(fā)送短信成功,保存短信驗證碼到redis數(shù)據(jù)庫中
                        # 開啟管道操作
                        pl = redis.pipeline()
                        pl.multi() # 接下來會在管道中執(zhí)行多條命令
                        # setex(變量名,有效期[秒],值 )
                        SMS_EXPIRE_TIME = 5 * 60 # 短信驗證碼的有效期
                        SMS_TIMES = 60  # 短信發(fā)送的間隔時間
                        # 把原來立即執(zhí)行的命令放置到管道
                        pl.setex("sms_%s" % phone, SMS_EXPIRE_TIME, sms_code)
                        pl.setex("times_%s" % phone, SMS_TIMES, 1)
            
                        # 統(tǒng)一執(zhí)行管道中的命令
                        pl.execute()
            
                    # 4. 響應(yīng)數(shù)據(jù)給客戶端
                    return Response({"message":result},status=status.HTTP_200_OK)

            urls.py

            from django.urls import path
            # jwt內(nèi)部實現(xiàn)的登陸視圖
            from rest_framework_jwt.views import obtain_jwt_token
            from .views import SMSCodeAPIView,
            
            urlpatterns=[
                path(r"login/", obtain_jwt_token ),
                path("sms/",SMSCodeAPIView.as_view()),
            ]

            utils.py,這是對用戶提交手機驗證碼后,對手機號和驗證碼的校對。判斷都正確后,返回一個對象,包括token,user信息等,

            from django.contrib.auth.backends import ModelBackend
            from django_redis import get_redis_connection
            
            
            def jwt_response_payload_handler(token, user=None, request=None):
                """
                自定義jwt認證成功返回數(shù)據(jù)
                :token  返回的jwt
                :user   當(dāng)前登錄的用戶信息[對象]
                :request 當(dāng)前本次客戶端提交過來的數(shù)據(jù)
                """
                return {
                    "token": token,
                    "id": user.id,
                    "username": user.username,
                }
            
            #實現(xiàn)多功能登錄
            import re
            from .models import User#查找用戶名或手機號是否已經(jīng)是我們的用戶
            def get_user_by_account(account):
                """
                根據(jù)帳號獲取user對象
                :param account: 賬號,可以是用戶名,也可以是手機號
                :return: User對象 或者 None
                """
                try:
                    if re.match("^1[3-9]d{9}$", account):
                        # 帳號為手機號
                        user = User.objects.get(phone=account)
                    else:
                        # 帳號為用戶名
                        user = User.objects.get(username=account)
                except User.DoesNotExist:
                    return None
                else:
                    return user
            #驗證用戶提交的短信和我們保存在redis里的信息是否一致
            def sms_code_verify(phone,sms_code):
                redis = get_redis_connection("sms_code")
                value=redis.get("sms_%s"%phone).decode()
                if value==sms_code:
                    return True
                return False
            
            class UsernameMobileAuthBackend(ModelBackend):
                """
                自定義用戶名或手機號認證
                """
                def authenticate(self, request, username=None, password=None, **kwargs):
                    user = get_user_by_account(username)      #當(dāng)密碼長度為4時,我判斷其為手機號和短信驗證碼登錄
                    if len(password)==4 and user is not None and sms_code_verify(username,password):
                        return user
                    elif user is not None and user.check_password(password):
                        return user
                    else:
                        return None

            2,前端代碼

            login組件

            <template>
              <div id="login">
                <div class="box">
                  <p>
                    <img src="../../assets/login_title.png" alt="">
                  </p>
                  <p class="sign">幫助有志向的年輕人通過努力學(xué)習(xí)獲得體面的工作和生活!</p>
                  <div class="pass" v-show="num==1">
                    <div class="title2 cursor">
                      <span @click="num=1" :class="num==1 ? "show" :""">密碼登錄</span>    
                      <span @click="num=2" :class="num==2 ? "show" :""">短信登錄</span>
                    </div>
                    <input v-model="username" type="text" class="ss" placeholder="用戶名 / 手機號碼">
                    <input v-model="password" type="password" class="ss" placeholder="密碼">
                    <div id="captcha" class="ss"></div>
                    <div class="t1">
                      <div class="left">
                        <input type="checkbox" class="cursor" v-model="remenber">
                        <div class="remenber cursor" >記住密碼</div>
                      </div>
                      <div class="right cursor">忘記密碼</div>
                    </div>
                    <button class="login_btn" @click="login1">登錄</button>
                    <div class="register">
                      沒有賬號
                      <span><router-link to="/register">立即注冊</router-link></span>
                    </div>
                  </div>
                  <div class="messge" v-show="num==2">
                    <div class="title2 cursor">
                      <span @click="num=1" :class="num==1 ? "show" :""">密碼登錄</span>    
                      <span @click="num=2" :class="num==2 ? "show" :""">短信登錄</span>
                    </div>
                    <input v-model="phone" type="text" class="ss" placeholder="手機號碼">
                    <div class="sms">
                      <input v-model="sms_code" type="text" class="ss">
                      <div class="content" @click="get_sms_code">{{content}}</div>
                    </div>
                    <button class="login_btn" @click="sms_login">登錄</button>
                    <div class="register">
                      沒有賬號
                      <span><router-link to="/register">立即注冊</router-link></span>
                    </div>
                  </div>
                </div>
              </div>
            </template>
            
            <script>
              export default {
                name:"login",
                data:function () {
                  return {
                    num:1,
                    username:"",
                    password:"",
                    remenber:"",
                    status:"",
                    content:"獲取驗證碼",
                    phone:"",
                    sms_code:"",
                  }
                },
                methods:{
                  //手機號和短信驗證碼登錄
                  sms_login:function(){
                    let _this=this;
                    this.$axios.post("http://127.0.0.1:8000/user/login/",{
                        "username":_this.phone,
                        "password":_this.sms_code,
                      },{responseType:"json"})
                      .then(function (res) {
                        sessionStorage.token=res.data.token;
                         _this.$router.go(-1);
                      }).catch(function (error) {
                      console.log(error.response)
                    });
                  },
                  //獲取短信驗證碼
                  get_sms_code:function(){
                    let reg = /1[3-9]{2}d{8}/;
                    if( reg.test(this.phone) ){
                      if(this.content == "獲取驗證碼"){
                        this.content=60;
                        let _this=this;
                        let tt=setInterval(function () {
                          if (_this.content>=1){
                            _this.content--
                          }
                          else {
                            _this.content="獲取驗證碼";
                            clearInterval(tt)
                          }
                        },1000);
                        this.$axios.get("http://127.0.0.1:8000/user/sms?type=login&phone="+this.phone)
                          .then(function (res) {
                            if(res.data.message==0){
                              alert("驗證碼發(fā)送成功")
                            }
                          }).catch(function (error) {
                            console.log(error.response)
                          })
                      }
                    }else {
                      alert("手機號碼有誤")
                    }
                  },
                  //用戶名和密碼登錄
                  login1:function () {
                    if (this.status==1){
                      let _this=this;
                      this.$axios.post("http://127.0.0.1:8000/user/login/",{
                        "username":_this.username,
                        "password":_this.password,
                      },{responseType:"json"})
                      .then(function (res) {
                        if (res.status==200){
                          if (_this.remenber){
                            sessionStorage.removeItem("token");
                            localStorage.token=res.data.token;
                          }
                          else {
                            localStorage.removeItem("token");
                            sessionStorage.token=res.data.token
                          }
                          _this.$router.go(-1);
                        }
                        else {
                          alert("用戶名或密碼錯誤")
                        }
                      })
                      .catch(function (error) {
                        alert(error.response.data.non_field_errors[0]);
                        console.log(error.response.data.non_field_errors);
                      });
                    }
                    else {
                      alert("驗證碼錯誤")
                    }
                  },
                  handlerPopup:function (captchaObj) {
                    let _this=this;
                    captchaObj.onSuccess(function () {
                       var validate = captchaObj.getValidate();
                       _this.$axios.post("http://127.0.0.1:8000/user/yzm/",{
                                geetest_challenge: validate.geetest_challenge,
                                geetest_validate: validate.geetest_validate,
                                geetest_seccode: validate.geetest_seccode,
                            },{
                              responseType:"json",
                        }).then(function (res) {
                          _this.status=res.data.status
                       }).catch(function (error) {
                         console.log(error)
                       })
                    });
                    captchaObj.appendTo("#captcha");
                  }
                },
                created:function () {
                  let _this=this;
                  this.$axios.get("http://127.0.0.1:8000/user/yzm")
                    .then(function (res) {
                      let data=JSON.parse(res.data);
                      initGeetest({
                            width:"350px",
                            gt: data.gt,
                            challenge: data.challenge,
                            product: "popup",
                            offline: !data.success
                        }, _this.handlerPopup);
                    }).catch(function (error) {
                      console.log(error)
                  })
                }
                
              }
            </script>
            
            <style scoped>
            #login{
              background: url("../../assets/Login.jpg");
              background-size: 100% 100%;
              height: 100%;
              position: fixed;
              width: 100%;
            }
            .box{
              width: 500px;
              height: 600px;
              margin: 0 auto;
              margin-top: 200px;
              text-align: center;
            }
            .box img{
              width: 190px;
              height: auto;
            }
            .box p{
              margin: 0;
            }
            .sign{
              font-size: 18px;
              color: #fff;
              letter-spacing: .29px;
              padding-top: 10px;
              padding-bottom: 50px;
            }
            .pass{
              width: 400px;
              height: 460px;
              margin: 0 auto;
              background-color: white;
              border-radius: 4px;
            }
            .messge{
              width: 400px;
              height: 390px;
              margin: 0 auto;
              background-color: white;
              border-radius: 4px;
            }
            .title2{
              width: 350px;
              font-size: 20px;
              color: #9b9b9b;
              padding-top: 50px;
              border-bottom: 1px solid #e6e6e6;
              margin: 0 auto;
              margin-bottom: 20px;
            }
            .ss{
              width: 350px;
              height: 45px;
              border-radius: 4px;
              border: 1px solid #d9d9d9;
              text-indent: 20px;
              font-size: 14px;
              margin-bottom: 20px;
            }
            .pass .t1{
              width: 350px;
              margin: 0 auto;
              height: 20px;
              line-height: 20px;
              font-size: 12px;
              text-align: center;
              position: relative;
            }
            .t1 .right{
              position: absolute;
              right: 0;
            }
            .remenber{
              display: inline-block;
              position: absolute;
              left: 20px;
            }
            .left input{
              position: absolute;
              left:0;
              width: 14px;
              height: 14px;
            }
            .login_btn{
              width: 350px;
              height: 45px;
              background: #ffc210;
              border-radius: 5px;
              font-size: 16px;
              color: #fff;
              letter-spacing: .26px;
              margin-top: 30px;
              outline: none;
              border:none;
              cursor: pointer;
            }
            .register{
              margin-top: 20px;
              font-size: 14px;
              color: #9b9b9b;
            }
            .register span{
              color: #ffc210;
              cursor: pointer;
            }
            .cursor{
              cursor: pointer;
            }
            .show{
              display: inline-block;
              padding-bottom: 5px;
              border-bottom: 2px solid orange;
              color: #4a4a4a;
            }
            a{
              text-decoration: none;
              color: #ffc210;
            }
            #captcha{
              margin: 0 auto;
              height: 44px;
            }
            .sms{
              position: relative;
              width: 350px;
              height: 45px;
              margin: 0 auto;
              line-height: 45px;
            }
            .sms .content{
              position: absolute;
              top:0;
              right: 10px;
              color: orange;
              border-left: 1px solid orange;
              padding-left: 10px;
              cursor: pointer;
            
            }
            </style>

            前端獲取短信驗證碼:

            //獲取短信驗證碼
                  get_sms_code:function(){
                    let reg = /1[3-9]{2}d{8}/;    //當(dāng)手機號為為真實手機號,才可以觸發(fā)獲取驗證碼
                    if( reg.test(this.phone) ){    //當(dāng)頁面上顯示為‘獲取驗證碼"時,才可以觸發(fā)獲取驗證碼請求;當(dāng)進入倒計時,點擊不能觸發(fā)獲取驗證碼請求
                      if(this.content == "獲取驗證碼"){     //成功發(fā)送獲取驗證碼請求之后開始倒計時60秒
                        this.content=60;
                        let _this=this;
                        let tt=setInterval(function () {
                          if (_this.content>=1){
                            _this.content--
                          }
                          else {
                            _this.content="獲取驗證碼";
                            clearInterval(tt)
                          }
                        },1000);
                        this.$axios.get("http://127.0.0.1:8000/user/sms?type=login&phone="+this.phone)
                          .then(function (res) {
                            if(res.data.message==0){
                              alert("驗證碼發(fā)送成功")
                            }
                          }).catch(function (error) {
                            console.log(error.response)
                          })
                      }
                    }else {
                      alert("手機號碼有誤")
                    }
                  },

            前端用手機號和短信驗證碼登錄:

            //獲取短信驗證碼
                  get_sms_code:function(){
                    let reg = /1[3-9]{2}d{8}/;    //當(dāng)手機號為為真實手機號,才可以觸發(fā)獲取驗證碼
                    if( reg.test(this.phone) ){    //當(dāng)頁面上顯示為‘獲取驗證碼"時,才可以觸發(fā)獲取驗證碼請求;當(dāng)進入倒計時,點擊不能觸發(fā)獲取驗證碼請求
                      if(this.content == "獲取驗證碼"){     //成功發(fā)送獲取驗證碼請求之后開始倒計時60秒
                        this.content=60;
                        let _this=this;
                        let tt=setInterval(function () {
                          if (_this.content>=1){
                            _this.content--
                          }
                          else {
                            _this.content="獲取驗證碼";
                            clearInterval(tt)
                          }
                        },1000);
                        this.$axios.get("http://127.0.0.1:8000/user/sms?type=login&phone="+this.phone)
                          .then(function (res) {
                            if(res.data.message==0){
                              alert("驗證碼發(fā)送成功")
                            }
                          }).catch(function (error) {
                            console.log(error.response)
                          })
                      }
                    }else {
                      alert("手機號碼有誤")
                    }
                  },

            感謝各位的閱讀,以上就是“vue怎么實現(xiàn)短信驗證碼”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對vue怎么實現(xiàn)短信驗證碼這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

            本文標題:vue怎么實現(xiàn)短信驗證碼
            網(wǎng)頁網(wǎng)址:http://www.jbt999.com/article14/gseoge.html

            成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、域名注冊微信公眾號、網(wǎng)站營銷、手機網(wǎng)站建設(shè)、網(wǎng)站制作

            廣告

            聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

            外貿(mào)網(wǎng)站建設(shè)

              <del id="d4fwx"><form id="d4fwx"></form></del>
              <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

                    <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
                  • 欧美成人AAA片一区国产精品 | 91乱伦网| 亚洲视频在线网站 | 日日夜夜拍 | 久久久久伊人 |