Vue_注册登录(短信验证码登录)
?
一、前言? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
1、動(dòng)態(tài)獲取圖片驗(yàn)證碼
2、實(shí)現(xiàn)手機(jī)驗(yàn)證碼登錄(工具準(zhǔn)備)
3、手機(jī)驗(yàn)證碼登錄(后臺實(shí)現(xiàn))
3、前臺實(shí)現(xiàn)
?
二、主要內(nèi)容? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
1、動(dòng)態(tài)獲取圖片驗(yàn)證碼
? ? (1)請求的接口如下,返回的是一張svg的圖片
## 獲取一次性驗(yàn)證碼### 請求URL:http://localhost:3000/captcha ### 請求方式:? ? ?(2)初次顯示圖片,可以直接在image中的src中請求路徑直接得到
<!--第一次顯示直接請求http://localhost:4000下面的--> <!--點(diǎn)擊圖片的時(shí)候要更新圖片,注冊一個(gè)點(diǎn)擊事件--> <input type="text" maxlength="11" placeholder="驗(yàn)證碼" v-model="captche"> <img class="get_verification" src="http://localhost:4000/captcha" alt="captcha" @click='getCaptcha'>? ? ? (3)點(diǎn)擊圖片的時(shí)候更新,methods中調(diào)用方法
//獲取圖片驗(yàn)證碼 getCaptcha(event){console.log(this) console.log(event.target)event.target.src="http://localhost:4000/captcha?Time="+Date.now()}?
?2、實(shí)現(xiàn)手機(jī)驗(yàn)證碼登錄(工具準(zhǔn)備)
? ? (1)這里用到“容聯(lián)通信云”:https://www.yuntongxun.com注冊登錄好之后,每個(gè)人都有不同的id號
? ? ? ? ? ?
? ?(2)然后選擇你要的驗(yàn)證類型
? ? ? ? ? ??
?
? ? (3)你需要添加一個(gè)測試號碼來接收驗(yàn)證短信
? ? ?
? ? ?(4)接下來就可以根據(jù)官方文檔寫代碼了
?
3、手機(jī)驗(yàn)證碼登錄(后臺實(shí)現(xiàn))
? ? (1)后臺項(xiàng)目結(jié)構(gòu)如圖所示
? ? ?
? ? (2)發(fā)送shengchen
var md5 = require('blueimp-md5') var moment = require('moment') var Base64 = require('js-base64').Base64; var request = require('request');/*生成指定長度的隨機(jī)數(shù)*/ function randomCode(length) {var chars = ['0','1','2','3','4','5','6','7','8','9'];var result = ""; //統(tǒng)一改名: alt + shift + Rfor(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;/* 向指定號碼發(fā)送指定驗(yàn)證碼*/ 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. 準(zhǔn)備請求url/*1.使用MD5加密(賬戶Id + 賬戶授權(quán)令牌 + 時(shí)間戳)。其中賬戶Id和賬戶授權(quán)令牌根據(jù)url的驗(yàn)證級別對應(yīng)主賬戶。時(shí)間戳是當(dāng)前系統(tǒng)時(shí)間,格式"yyyyMMddHHmmss"。時(shí)間戳有效時(shí)間為24小時(shí),如:201404161420302.SigParameter參數(shù)需要大寫,如不能寫成sig=abcdefg而應(yīng)該寫成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. 準(zhǔn)備請求體var body = {to : phone,appId : AppID,templateId : '1',"datas":[code,"1"]}//body = JSON.stringify(body);//3. 準(zhǔn)備請求頭/*1.使用Base64編碼(賬戶Id + 冒號 + 時(shí)間戳)其中賬戶Id根據(jù)url的驗(yàn)證級別對應(yīng)主賬戶2.冒號為英文冒號3.時(shí)間戳是當(dāng)前系統(tǒng)時(shí)間,格式"yyyyMMddHHmmss",需與SigParameter中時(shí)間戳相同。*/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. 發(fā)送請求, 并得到返回的結(jié)果, 調(diào)用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;/*調(diào)用方式 sendCode('13716**2779', randomCode(6), function (success) {console.log(success); })*/?
? (2)在index.js中調(diào)用
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} // 查詢時(shí)過濾掉 const sms_util = require('../util/sms_util') const users = {} const ajax = require('../api/ajax') var svgCaptcha = require('svg-captcha')/* 發(fā)送驗(yàn)證碼短信 */ router.get('/sendcode', function (req, res, next) {//1. 獲取請求參數(shù)數(shù)據(jù)var phone = req.query.phone;//2. 處理數(shù)據(jù)//生成驗(yàn)證碼(6位隨機(jī)數(shù))var code = sms_util.randomCode(6);//發(fā)送給指定的手機(jī)號 console.log(`向${phone}發(fā)送驗(yàn)證碼短信: ${code}`);sms_util.sendCode(phone, code, function (success) {//success表示是否成功if (success) {users[phone] = codeconsole.log(users[phone])console.log('保存驗(yàn)證碼: ', phone, code)res.send({"code": 0})} else {//3. 返回響應(yīng)數(shù)據(jù)res.send({"code": 1, msg: '短信驗(yàn)證碼發(fā)送失敗'})}}) })/* 短信登陸 */ 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: '手機(jī)號或驗(yàn)證碼不正確'});return;}//刪除保存的codedelete users[phone];UserModel.findOne({phone}, function (err, user) {if (user) {req.session.userid = user._idres.send({code: 0, data: user})} else {//存儲數(shù)據(jù)const userModel = new UserModel({phone})userModel.save(function (err, user) {req.session.userid = user._idres.send({code: 0, data: user})})}})})?
3、前臺實(shí)現(xiàn)
? ? (1)輸入正確的手機(jī)號之后,點(diǎn)擊“獲取驗(yàn)證碼”,會異步調(diào)用getCode()方法
a:頁面行為
? ? ?
b 調(diào)用getCode方法獲取驗(yàn)證碼
?
c在methods中定義獲取驗(yàn)證碼函數(shù)
// 異步獲取短信驗(yàn)證碼 async getCode () {// 如果當(dāng)前沒有計(jì)時(shí)if(!this.computeTime) {// 啟動(dòng)倒計(jì)時(shí)this.computeTime = 60this.intervalId = setInterval(() => {this.computeTime--if(this.computeTime<=0) {// 停止計(jì)時(shí)clearInterval(this.intervalId)}}, 1000)// 發(fā)送ajax請求(向指定手機(jī)號發(fā)送驗(yàn)證碼短信)const result = await reqSendCode(this.phone)if(result.code===1) {// 顯示提示this.showAlert(result.msg)// 停止計(jì)時(shí)if(this.computeTime) {this.computeTime = 0clearInterval(this.intervalId)this.intervalId = undefined}}}},d.異步請求時(shí)會調(diào)用自己封裝的請求函數(shù)
//6.發(fā)送短信驗(yàn)證碼 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 promiseif (type === 'GET') {// 準(zhǔn)備url query 參數(shù)數(shù)據(jù)let dataStr = '' //數(shù)據(jù)拼接字符串Object.keys(data).forEach(key => {dataStr += key + '=' + data[key] + '&'})if (dataStr !== '') {dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))url = url + '?' + dataStr}// 發(fā)送get 請求promise = axios.get(url)} else {// 發(fā)送post 請求promise = axios.post(url, data)}promise.then(response => {resolve(response.data)}).catch(error => {reject(error)})}) } ajax函數(shù)封裝?
e.后臺接受到get請求,會執(zhí)行后臺index.js中的get請求方式,先生成驗(yàn)證碼,并且提示到手機(jī)上
router.get('/sendcode', function (req, res, next) {//1. 獲取請求參數(shù)數(shù)據(jù)var phone = req.query.phone;//2. 處理數(shù)據(jù)//生成驗(yàn)證碼(6位隨機(jī)數(shù))var code = sms_util.randomCode(6);//發(fā)送給指定的手機(jī)號 console.log(`向${phone}發(fā)送驗(yàn)證碼短信: ${code}`);sms_util.sendCode(phone, code, function (success) {//success表示是否成功if (success) {users[phone] = codeconsole.log(users[phone])console.log('保存驗(yàn)證碼: ', phone, code)res.send({"code": 0})} else {//3. 返回響應(yīng)數(shù)據(jù)res.send({"code": 1, msg: '短信驗(yàn)證碼發(fā)送失敗'})}}) })f.用戶收到驗(yàn)證碼,并且輸入點(diǎn)擊“登錄”按鈕,提交表單,再次對服務(wù)器發(fā)起post請求,服務(wù)器在驗(yàn)證
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: '手機(jī)號或驗(yàn)證碼不正確'});return;}//刪除保存的codedelete users[phone];UserModel.findOne({phone}, function (err, user) {if (user) {req.session.userid = user._idres.send({code: 0, data: user})} else {//存儲數(shù)據(jù)const userModel = new UserModel({phone})userModel.save(function (err, user) {req.session.userid = user._idres.send({code: 0, data: user})})}})})g.前臺接受到后臺的響應(yīng)數(shù)據(jù)之后,還需要進(jìn)行以下操作
1)將電話號碼保存到vuex的state中去
2)進(jìn)行路由跳轉(zhuǎn)
if(this.loginWay) { // 短信登陸const {rightPhone, phone, code} = thisif(!this.rightPhone) {// 手機(jī)號不正確this.showAlert('手機(jī)號不正確')return} else if(!/^\d{6}$/.test(code)) {// 驗(yàn)證必須是6位數(shù)字this.showAlert('驗(yàn)證必須是6位數(shù)字')return}// 發(fā)送ajax請求短信登陸result = await reqSmsLogin(phone, code)}// 停止計(jì)時(shí)if(this.computeTime) {this.computeTime = 0clearInterval(this.intervalId)this.intervalId = undefined}// 根據(jù)結(jié)果數(shù)據(jù)處理if(result.code===0) {const user = result.datacosole.log(user)// 將user保存到vuex的statethis.$store.dispatch('recordUser', user)// 去個(gè)人中心界面this.$router.replace('/profile')} else {// 顯示新的圖片驗(yàn)證碼this.getCaptcha()// 顯示警告提示const msg = result.msgthis.showAlert(msg)}}?
?
?
?
三、總結(jié)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
轉(zhuǎn)載于:https://www.cnblogs.com/xxm980617/p/10822624.html
總結(jié)
以上是生活随笔為你收集整理的Vue_注册登录(短信验证码登录)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python-语言播报
- 下一篇: vue路由切换和用location切换u