Vue_註冊登陸(短信驗證碼登陸)

 

1、前言                                                                            vue

一、動態獲取圖片驗證碼ios

二、實現手機驗證碼登陸(工具準備)ajax

三、手機驗證碼登陸(後臺實現)vuex

三、前臺實現express

 

2、主要內容                                                                     json

一、動態獲取圖片驗證碼axios

    (1)請求的接口以下,返回的是一張svg的圖片api

## 獲取一次性驗證碼
     
### 請求URL:
    http://localhost:3000/captcha

### 請求方式:

     (2)初次顯示圖片,能夠直接在image中的src中請求路徑直接獲得promise

 <!--第一次顯示直接請求http://localhost:4000下面的-->
<!--點擊圖片的時候要更新圖片,註冊一個點擊事件-->
<input type="text" maxlength="11" placeholder="驗證碼" v-model="captche">
<img class="get_verification" src="http://localhost:4000/captcha" alt="captcha" @click='getCaptcha'>

      (3)點擊圖片的時候更新,methods中調用方法服務器

 //獲取圖片驗證碼
      getCaptcha(event){
       console.log(this) 
       console.log(event.target)
        event.target.src="http://localhost:4000/captcha?Time="+Date.now()

      }

 

 二、實現手機驗證碼登陸(工具準備)

    (1)這裏用到「容聯通訊雲」:https://www.yuntongxun.com註冊登陸好以後,每一個人都有不一樣的id號

           

   (2)而後選擇你要的驗證類型

            

 

    (3)你須要添加一個測試號碼來接收驗證短信

     

     (4)接下來就能夠根據官方文檔寫代碼了

 

三、手機驗證碼登陸(後臺實現)

    (1)後臺項目結構如圖所示

     

    (2)發送shengchen

var md5 = require('blueimp-md5')
var moment = require('moment')
var Base64 = require('js-base64').Base64;
var request = require('request');

/*
 生成指定長度的隨機數
 */
function randomCode(length) {
    var chars = ['0','1','2','3','4','5','6','7','8','9'];
    var result = ""; //統一更名: alt + shift + R
    for(var i = 0; i < length ; i ++) {
        var index = Math.ceil(Math.random()*9);
        result += chars[index];
    }
    return result;
}
// console.log(randomCode(6));
exports.randomCode = randomCode;

/*
向指定號碼發送指定驗證碼
 */
function sendCode(phone, code, callback) {
    var ACCOUNT_SID = '8a216da86a960fd9016a96d0eb580180';
    var AUTH_TOKEN = '3abf248c565446d0bf10d46eb62dee07';
    var Rest_URL = 'https://app.cloopen.com:8883';
    var AppID = '8a216da86a960fd9016a96d0eba80186';
    //1. 準備請求url
    /*
     1.使用MD5加密(帳戶Id + 帳戶受權令牌 + 時間戳)。其中帳戶Id和帳戶受權令牌根據url的驗證級別對應主帳戶。
     時間戳是當前系統時間,格式"yyyyMMddHHmmss"。時間戳有效時間爲24小時,如:20140416142030
     2.SigParameter參數須要大寫,如不能寫成sig=abcdefg而應該寫成sig=ABCDEFG
     */
    var sigParameter = '';
    var time = moment().format('YYYYMMDDHHmmss');
    sigParameter = md5(ACCOUNT_SID+AUTH_TOKEN+time);
    var url = Rest_URL+'/2013-12-26/Accounts/'+ACCOUNT_SID+'/SMS/TemplateSMS?sig='+sigParameter;

    //2. 準備請求體
    var body = {
        to : phone,
        appId : AppID,
        templateId : '1',
        "datas":[code,"1"]
    }
    //body = JSON.stringify(body);

    //3. 準備請求頭
    /*
     1.使用Base64編碼(帳戶Id + 冒號 + 時間戳)其中帳戶Id根據url的驗證級別對應主帳戶
     2.冒號爲英文冒號
     3.時間戳是當前系統時間,格式"yyyyMMddHHmmss",需與SigParameter中時間戳相同。
     */
    var authorization = ACCOUNT_SID + ':' + time;
    authorization = Base64.encode(authorization);
    var headers = {
        'Accept' :'application/json',
        'Content-Type' :'application/json;charset=utf-8',
        'Content-Length': JSON.stringify(body).length+'',
        'Authorization' : authorization
    }

    //4. 發送請求, 並獲得返回的結果, 調用callback
      // callback(true);
    request({
        method : 'POST',
        url : url,
        headers : headers,
        body : body,
        json : true
    }, function (error, response, body) {
        console.log(error, response, body);
        callback(body.statusCode==='000000');
        // callback(true);
    });
}
exports.sendCode = sendCode;

/*調用方式
sendCode('13716**2779', randomCode(6), function (success) {
    console.log(success);
})*/

 

  (2)在index.js中調用

var express = require('express');
var router = express.Router();
const md5 = require('blueimp-md5')
const models = require('../db/models')
const UserModel = models.getModel('user')
const _filter = {'pwd': 0, '__v': 0} // 查詢時過濾掉
const sms_util = require('../util/sms_util')
const users = {}
const ajax = require('../api/ajax')
var svgCaptcha = require('svg-captcha')


/*
發送驗證碼短信
*/
router.get('/sendcode', function (req, res, next) {
  //1. 獲取請求參數數據
  var phone = req.query.phone;
  //2. 處理數據
  //生成驗證碼(6位隨機數)
  var code = sms_util.randomCode(6);
  //發送給指定的手機號
  console.log(`向${phone}發送驗證碼短信: ${code}`);
  sms_util.sendCode(phone, code, function (success) {//success表示是否成功
    if (success) {
      users[phone] = code
      console.log(users[phone])
      console.log('保存驗證碼: ', phone, code)
      res.send({"code": 0})
    } else {
      //3. 返回響應數據
      res.send({"code": 1, msg: '短信驗證碼發送失敗'})
    }
  })
})

/*
短信登錄
*/
router.post('/login_sms', function (req, res, next) {
  var phone = req.body.phone;
  var code = req.body.code;
  console.log('/login_sms', phone, code);
  if (users[code] != code) {
    res.send({code: 1, msg: '手機號或驗證碼不正確'});
    return;
  }
  //刪除保存的code
  delete users[phone];


  UserModel.findOne({phone}, function (err, user) {
    if (user) {
      req.session.userid = user._id
      res.send({code: 0, data: user})
    } else {
      //存儲數據
      const userModel = new UserModel({phone})
      userModel.save(function (err, user) {
        req.session.userid = user._id
        res.send({code: 0, data: user})
      })
    }
  })

})

 

三、前臺實現

    (1)輸入正確的手機號以後,點擊「獲取驗證碼」,會異步調用getCode()方法

a:頁面行爲

     

b 調用getCode方法獲取驗證碼

 

c在methods中定義獲取驗證碼函數

// 異步獲取短信驗證碼
      async getCode () {
        // 若是當前沒有計時
        if(!this.computeTime) {
          // 啓動倒計時
          this.computeTime = 60
          this.intervalId = setInterval(() => {
            this.computeTime--
            if(this.computeTime<=0) {
              // 中止計時
              clearInterval(this.intervalId)
            }
          }, 1000)

          // 發送ajax請求(向指定手機號發送驗證碼短信)
          const result = await reqSendCode(this.phone)
          if(result.code===1) {
            // 顯示提示
            this.showAlert(result.msg)
            // 中止計時
            if(this.computeTime) {
              this.computeTime = 0
              clearInterval(this.intervalId)
              this.intervalId = undefined
            }
          }
        }
      },

d.異步請求時會調用本身封裝的請求函數

//6.發送短信驗證碼
export const reqSendCode = (phone)=>ajax('/api/sendcode', {phone})
import axios from 'axios'
export default function ajax(url = '', data = {}, type = 'GET') {
        return new Promise(function (resolve, reject) {
        let promise
        if (type === 'GET') {
        // 準備url query 參數數據
        let dataStr = '' //數據拼接字符串
        Object.keys(data).forEach(key => {
        dataStr += key + '=' + data[key] + '&'
        })
        if (dataStr !== '') {
        dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
        url = url + '?' + dataStr
        }
        // 發送get 請求
        promise = axios.get(url)
        } else {
        // 發送post 請求
        promise = axios.post(url, data)
        }
        promise.then(response => {
        resolve(response.data)
        })
        .catch(error => {
        reject(error)
        })
        })
}
ajax函數封裝

 

e.後臺接受到get請求,會執行後臺index.js中的get請求方式,先生成驗證碼,而且提示到手機上

router.get('/sendcode', function (req, res, next) {
  //1. 獲取請求參數數據
  var phone = req.query.phone;
  //2. 處理數據
  //生成驗證碼(6位隨機數)
  var code = sms_util.randomCode(6);
  //發送給指定的手機號
  console.log(`向${phone}發送驗證碼短信: ${code}`);
  sms_util.sendCode(phone, code, function (success) {//success表示是否成功
    if (success) {
      users[phone] = code
      console.log(users[phone])
      console.log('保存驗證碼: ', phone, code)
      res.send({"code": 0})
    } else {
      //3. 返回響應數據
      res.send({"code": 1, msg: '短信驗證碼發送失敗'})
    }
  })
})

f.用戶收到驗證碼,而且輸入點擊「登陸」按鈕,提交表單,再次對服務器發起post請求,服務器在驗證

router.post('/login_sms', function (req, res, next) {
  var phone = req.body.phone;
  var code = req.body.code;
  console.log('/login_sms', phone, code);
  if (users[code] != code) {
    res.send({code: 1, msg: '手機號或驗證碼不正確'});
    return;
  }
  //刪除保存的code
  delete users[phone];


  UserModel.findOne({phone}, function (err, user) {
    if (user) {
      req.session.userid = user._id
      res.send({code: 0, data: user})
    } else {
      //存儲數據
      const userModel = new UserModel({phone})
      userModel.save(function (err, user) {
        req.session.userid = user._id
        res.send({code: 0, data: user})
      })
    }
  })

})

g.前臺接受到後臺的響應數據以後,還須要進行如下操做

1)將電話號碼保存到vuex的state中去

2)進行路由跳轉

if(this.loginWay) {  // 短信登錄
          const {rightPhone, phone, code} = this
          if(!this.rightPhone) {
            // 手機號不正確
            this.showAlert('手機號不正確')
            return
          } else if(!/^\d{6}$/.test(code)) {
            // 驗證必須是6位數字
            this.showAlert('驗證必須是6位數字')
            return
          }
          // 發送ajax請求短信登錄
          result = await reqSmsLogin(phone, code)

        }
        // 中止計時
        if(this.computeTime) {
          this.computeTime = 0
          clearInterval(this.intervalId)
          this.intervalId = undefined
        }

        // 根據結果數據處理
        if(result.code===0) {
          const user = result.data
          cosole.log(user)
          // 將user保存到vuex的state
          this.$store.dispatch('recordUser', user)
          // 去我的中心界面
          this.$router.replace('/profile')
        } else {
          // 顯示新的圖片驗證碼
          this.getCaptcha()
          // 顯示警告提示
          const msg = result.msg
          this.showAlert(msg)
        }
      }

 

 

 

 

3、總結                                                                            

相關文章
相關標籤/搜索