微信小程序授權(quán)登錄的優(yōu)雅處理方式
前言
當(dāng)微信小程序項(xiàng)目中涉及到獲取用戶信息并實(shí)現(xiàn)用戶登錄時(shí),可以通過(guò)微信官方提供的登錄能力方便地獲取微信的用戶身份標(biāo)識(shí),快速建立小程序內(nèi)的用戶體系。官方文檔只是提供如何去調(diào)用授權(quán)登錄,如果直接原封不動(dòng)的照搬文檔來(lái)進(jìn)行代碼編寫,這樣勢(shì)必會(huì)造成代碼的維護(hù)性差,所以本篇著重介紹如果更優(yōu)雅的處理微信小程序的授權(quán)登錄。
授權(quán)登錄的基本流程
上圖是微信小程序官網(wǎng)提供的授權(quán)登錄基本流程圖,這里我只從前端開發(fā)的角度來(lái)講解一下該流程。
- 通過(guò)wx.login()獲取臨時(shí)登錄憑證code。
- 通過(guò)調(diào)用服務(wù)端提供的接口把code傳遞給服務(wù)端,然后服務(wù)端會(huì)返回給前端openid和sesstion_key。這就代表已經(jīng)成功完成授權(quán)登錄了,至于openid和sesstion_key的用途,后面再進(jìn)行講解。
大體的登錄流程搞清楚之后,就可以進(jìn)行代碼的編寫了。因?yàn)槲⑿盘峁┑腶pi接口調(diào)用不利于代碼維護(hù),所以我借助了promise進(jìn)行封裝處理(不了解的可以看ES6文檔,里面有詳細(xì)介紹),這樣做的好處就是以后可以鏈?zhǔn)秸{(diào)用接口,也可以結(jié)合async/await(ES6語(yǔ)法)將異步接口進(jìn)行同步處理。
get/post 接口的封裝處理
在根目錄中創(chuàng)建service文件夾,用于存放與接口相關(guān)的代碼,在service文件夾創(chuàng)建一個(gè)myRequest.js文件并對(duì)小程序的get/post請(qǐng)求進(jìn)行封裝處理,代碼如下:
//get請(qǐng)求封裝(跳頁(yè)判斷) //通過(guò)全局函數(shù)getApp可以獲取全局變量,需要全局的數(shù)據(jù)可以在根目錄下的app.js進(jìn)行設(shè)置 let app=getApp(); const myGet = (url, data)=>{ return new Promise((resolve, reject)=>{ wx.request({ url: `${app.globalData.HTTP}${url}`, data:data, method:"GET", //這個(gè)authorization就是含有openid和sesstion_key信息的值 header: { 'authorization': app.globalData.authorization},//獲取全局變量中的用戶信息,并放入到請(qǐng)求頭中 success:(res)=>{ if (res.data.code == 409) { //409代表用戶未進(jìn)行登錄,強(qiáng)制跳到寫好的登錄頁(yè) wx.navigateTo({ url: '../login/login' }) } else{ resolve(res.data); } }, fail:(res)=>{ reject(); } }) }) } //post請(qǐng)求封裝(跳頁(yè)判斷) const myPost = (url, data) => { return new Promise((resolve, reject) => { wx.request({ url: `${app.globalData.HTTP}${url}`, data: data, method: "POST", header: { 'authorization': app.globalData.authorization}, success: (res) => { if (res.data.code == 409){ wx.navigateTo({ url: '../login/login' }) }else{ resolve(res.data); } }, fail: (res) => { reject(); } }) }) } module.exports = { myGet, myPost, }
全局變量配置app.js代碼如下(注意全局變量數(shù)據(jù)會(huì)在刷新頁(yè)面或是重新進(jìn)入小程序之后初始化,并不能永久保存當(dāng)前的數(shù)據(jù)狀態(tài)):
//app.js App({ onLaunch: function() { //這里可以根據(jù)項(xiàng)目實(shí)際需求寫一些項(xiàng)目初始化需要執(zhí)行的代碼 }, globalData: { HTTP: "https://shop.yamecent.com/", //我們獲取openid和sesstion_key之后,會(huì)把它存放到小程序內(nèi)存的authorization中,這樣數(shù)據(jù)不會(huì)丟失,除非刪除該小程序 authorization: wx.getStorageSync('authorization') || "",//獲取存儲(chǔ)在小程序內(nèi)存中的authorization } })
授權(quán)登錄接口封裝
這部分封裝會(huì)用到async/await,將異步接口進(jìn)行同步處理,不了解的可以參看ES6文檔說(shuō)明,在service文件夾下創(chuàng)建login.js代碼如下:
const myRequest = require('./myRequest.js'); const app = getApp(); const HTTP = app.globalData.HTTP; //微信login接口獲取code封裝 const myLogin=()=>{ return new Promise((resolve, reject)=>{ wx.login({ success:(res)=>{ resolve(res.code); }, fail:(res)=>{ reject(res.errMsg); console.log("微信登錄獲取code失敗"); } }) }) } //獲取openid和session_key接口封裝 const getUserMsg=(myUrl,myData)=>{ return new Promise((resolve,reject)=>{ wx.request({ url: myUrl, method: "POST", data: myData, success:(res)=>{ if(res.data.code==500){ //獲取失敗 wx.showToast({ title: res.data.msg, icon: 'none', duration: 2000, mask:true, }) resolve(500);//失敗是返回500 }else{ resolve(res.data.data); } }, fail:(res)=>{ reject(res.data.msg); console.log("獲取openid和session_key接口失敗"); } }) }) } //封裝存儲(chǔ)(注意:這里的存儲(chǔ)過(guò)程是異步的) const mySetStorage=(key,val)=>{ return new Promise((resolve, reject) => { wx.setStorage({ key: key, data: val, success: () => { resolve(true); }, fail: () => { reject(false); } }) }) } //封裝獲取存儲(chǔ) const myGetStorage=(key)=>{ return new Promise((resolve,reject)=>{ wx.getStorage({ key: 'key', success: (res)=>{ resolve(res.data); }, fail:()=>{ reject("獲取存儲(chǔ)失敗"); } }) }) } //授權(quán)方法封裝 //sendData是通過(guò)授權(quán)按鈕獲取到的用戶信息,這里要作為參數(shù)傳遞給后臺(tái)來(lái)保存用戶的信息 //cb是授權(quán)登錄成功之后所要執(zhí)行的函數(shù),具體是什么功能的函數(shù),要根據(jù)項(xiàng)目需求而定,也可能不需要 const myAuthorize = (sendData,cb="") => { async function accredit() { wx.showLoading({ title: '認(rèn)證中', mask:true }) let code = await myLogin();//微信登陸獲取code接口 sendData.code=code; let author = await getUserMsg(`${HTTP}auth`, sendData);//獲取后臺(tái)openid sesstion_key接口 wx.hideLoading(); if(author==500){ return; } await mySetStorage("authorization", author.Authorization);//存到內(nèi)存中,進(jìn)入小程序中獲取并存入app.globalData中 app.globalData.authorization = author.Authorization; typeof cb == "function" && cb(author);//回調(diào)所需要用的登陸狀態(tài)參數(shù) //這里可以補(bǔ)充一下其它業(yè)務(wù)邏輯,如tabbar用戶購(gòu)物車數(shù)量等邏輯 wx.showToast({ title: '成功授權(quán)', icon: 'success', duration: 2000, mask: true }); } accredit(); } module.exports = { myAuthorize, mySetStorage, myGetStorage }
授權(quán)登錄封裝好了之后再看看如何在項(xiàng)目中如何使用,由于微信小程序授權(quán)只能通過(guò)button來(lái)觸發(fā),所以使用 button 組件,并將 open-type 指定為 getUserInfo 類型,獲取用戶基本信息。login.wxml代碼如下:
<button class='btn' open-type="getUserInfo" bindgetuserinfo='gotoLogin'>立即登錄</button>
login.js代碼如下:
// pages/login/login.js const myRequest = require('../../common/script/myRequest.js'); const login = require('../../common/script/login.js'); const app = getApp(); const HTTP = app.globalData.HTTP; Page({ /** * 頁(yè)面的初始數(shù)據(jù) */ data: { }, gotoLogin: function (e) { let sendOjb={};//用于存放用戶信息 if (e.detail.errMsg =="getUserInfo:ok"){ sendOjb = { avatar: e.detail.userInfo.avatarUrl, nickname: e.detail.userInfo.nickName, sex: e.detail.userInfo.gender, province: e.detail.userInfo.province, city: e.detail.userInfo.city}; login.myAuthorize(sendOjb,()=>{ wx.navigateBack();//成功之后返回之前的頁(yè)面,也可以根據(jù)項(xiàng)目需求寫一些其它的邏輯 }) }else{ } }, /** * 生命周期函數(shù)--監(jiān)聽頁(yè)面加載 */ onLoad: function (options) { }, })
結(jié)束語(yǔ)
以上代碼復(fù)制粘貼到自己的微信小程序項(xiàng)目中就能夠正常運(yùn)行,如有錯(cuò)誤或需要改進(jìn)的地方還請(qǐng)與我聯(lián)系,我將及時(shí)進(jìn)行改正。
到此這篇關(guān)于微信小程序授權(quán)登錄的優(yōu)雅處理方式的文章就介紹到這了,更多相關(guān)微信小程序授權(quán)登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中你不得不知道的Promise高級(jí)用法分享
在JavaScript中,Promise是一種解決異步編程問(wèn)題的重要方式,本文主要來(lái)和大家探討一下23個(gè)Promise的高級(jí)用法,每一個(gè)都在JavaScript的海洋中航行,讓開發(fā)者們能夠以更高效、優(yōu)雅的方式處理異步操作,希望對(duì)大就有所幫助2023-12-12jQuery javascript獲得網(wǎng)頁(yè)的高度與寬度的實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇jQuery javascript獲得網(wǎng)頁(yè)的高度與寬度的實(shí)現(xiàn)代碼。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考2016-04-04詳解Bootstrap的aria-label和aria-labelledby應(yīng)用
這篇文章主要介紹了詳解Bootstrap的aria-label和aria-labelledby應(yīng)用的相關(guān)資料,需要的朋友可以參考下2016-01-01當(dāng)鼠標(biāo)滑過(guò)超鏈接出現(xiàn)提示框效果實(shí)例
當(dāng)鼠標(biāo)滑過(guò)超鏈接出現(xiàn)提示框效果實(shí)例,需要的朋友可以參考一下2013-04-04Javascript浮點(diǎn)數(shù)乘積運(yùn)算出現(xiàn)多位小數(shù)的解決方法
這篇文章主要介紹了Javascript浮點(diǎn)數(shù)乘積運(yùn)算出現(xiàn)多位小數(shù)的解決方法,需要的朋友可以參考下2014-02-02JavaScript焦點(diǎn)事件、鼠標(biāo)事件和滾輪事件使用詳解
這篇文章主要介紹了JavaScript焦點(diǎn)事件、鼠標(biāo)事件和滾輪事件使用詳解,通過(guò)示例給大家講解的非常細(xì)致,有需要的小伙伴可以參考下。2016-01-01JS字符串false轉(zhuǎn)boolean的方法(推薦)
下面小編就為大家?guī)?lái)一篇JS字符串false轉(zhuǎn)boolean的方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03