摘要:首先附上官方文檔地址和授權(quán)流程官方地址流程圖大致邏輯授權(quán)發(fā)送到服務(wù)器獲取保存在小程序緩存內(nèi)調(diào)用和獲取用戶信息登錄成功返回訪問記錄登錄狀態(tài)執(zhí)行登錄成功監(jiān)聽失敗則不監(jiān)聽直接上代碼,一下均為小程序組件模式有興趣的可以看下官方文檔創(chuàng)建自
首先附上官方文檔地址和授權(quán)流程
官方地址:https://developers.weixin.qq....
流程圖:
大致邏輯:授權(quán) -> 發(fā)送code到服務(wù)器獲取session_key - > 保存在小程序緩存內(nèi) -> 調(diào)用wx.getUserInfo和session_key獲取用戶信息 -> 登錄成功返回訪問token -> 記錄登錄狀態(tài) -> 執(zhí)行登錄成功監(jiān)聽(失敗則不監(jiān)聽)
直接上代碼,一下均為小程序組件模式有興趣的可以看下官方文檔
創(chuàng)建components(自定義名稱)文件夾pages文件夾同級主要放置組件文件
創(chuàng)建 authorize (自定義名稱)文件夾 還是一樣的創(chuàng)建 對應(yīng)的authorize.js ,authorize.wxml .authorize.wxss,authorize.json特別注意這里的 authorize.json 文件里面要定義當(dāng)前頁面為組件
{
"component": true
}
到這里準(zhǔn)備工作完成
authorize.js 換成組件的寫法,具體參考小程序官方文檔,這里展示我定義的
Component({ //組件的對外屬性 說的確實很官方,用過vue組件的就很容易理解這點 //父級向子級傳值這里就是接收值得地方 properties:{ //名稱要和父級綁定的名稱相同 //這里主要是控制自動授權(quán)彈框是否顯示 true=隱藏 false=顯示 iShidden:{ type:Boolean,//定義類型 value: true,//定義默認(rèn)值 }, //是否自動登錄 這里主要用于沒有授權(quán)是否自動彈出授權(quán)提示框 //**用在不自動登錄頁面但是某些操作需要授權(quán)登錄** isAuto:{ type: Boolean, value: true, }, }, //組件的內(nèi)部數(shù)據(jù),和 properties 一同用于組件的模板渲染 data:{ cloneIner:null }, //組件所在頁面的生命周期聲明對象 pageLifetimes:{ //頁面隱藏 hide:function(){ //關(guān)閉頁面時銷毀定時器 if(this.data.cloneIner) clearInterval(this.data.clearInterval); }, //頁面打開 show:function(){ //打開頁面銷毀定時器 if (this.data.cloneIner) clearInterval(this.data.clearInterval); }, }, //組件生命周期函數(shù),在組件實例進(jìn)入頁面節(jié)點樹時執(zhí)行 attached(){ }, //組件的方法 methods:{ } });
注:以下的方法都需寫在 methods 內(nèi)
第一步:未授權(quán)用戶判斷是否執(zhí)行授權(quán)還是直接進(jìn)行獲取用戶信息
//檢測登錄狀態(tài)并執(zhí)行自動登錄 setAuthStatus(){ var that = this; that.setErrorCount(); wx.getSetting({ success(res) { //這里會檢測是否授權(quán),如果授權(quán)了會直接調(diào)用自動登錄 if (!res.authSetting["scope.userInfo"]) { //沒有授權(quán)不會自動彈出登錄框 if (that.data.isAuto === false) return; //自動彈出授權(quán) that.setData({ iShidden: false }); } else { //自動登錄 that.setData({ iShidden: true }); if (app.globalData.token) { //這里是授權(quán)回調(diào) that.triggerEvent("onLoadFun", app.globalData.token); that.WatchIsLogin(); } else { wx.showLoading({ title: "正在登錄中" }); //這里是已授權(quán)調(diào)用wx.getUserInfo that.getUserInfoBydecryptCode(); } } } }) }
第二步,沒有授權(quán)執(zhí)行打開授權(quán)彈出框
//授權(quán) setUserInfo(e){ var that = this, pdata={}; pdata.userInfo = e.detail.userInfo; pdata.spid = app.globalData.spid; wx.showLoading({ title: "正在登錄中" }); wx.login({ success: function (res) { if (!res.code) return app.Tips({ title: "登錄失??!" + res.errMsg}); //獲取session_key并緩存 that.getSessionKey(res.code, function () { that.getUserInfoBydecryptCode(); }); }, fail() { wx.hideLoading(); } }) }, //從緩存中獲取session_key,如果沒有則請求服務(wù)器再次緩存 getSessionKey(code,successFn,errotFn){ var that=this; wx.checkSession({ success: function (res){ if(wx.getStorageSync("session_key")) successFn && successFn(); else that.setCode(code, successFn, errotFn); }, fail:function(){ that.setCode(code, successFn, errotFn); } }); }, //訪問服務(wù)器獲得session_key 并存入緩存中 setCode(code, successFn, errotFn){ var that = this; app.basePost(app.U({ c: "Login", a: "setCode" }), { code: code }, function (res) { wx.setStorageSync("session_key", res.data.session_key); successFn && successFn(res); }, function (res) { if (errotFn) errotFn(res); else return app.Tips({ title: "獲取session_key失敗" }); }); }
第三步:執(zhí)行g(shù)etUserInfoBydecryptCode 登錄獲取訪問權(quán)限
getUserInfoBydecryptCode: function () { var that = this; var session_key = wx.getStorageSync("session_key") //沒有獲取到session_key,打開授權(quán)頁面 //這里必須的判斷存在緩存中的session_key是否存在,因為在第一步的時候,判斷了 //授權(quán)了將自動執(zhí)行獲取用戶信息的方法 if (!session_key) { wx.hideLoading(); if(that.data.isAuto) that.setData({ iShidden: false }) return false; }; wx.getUserInfo({ lang: "zh_CN", success: function (res) { var pdata = res; pdata.userInfo = res.userInfo; pdata.spid = app.globalData.spid;//獲取推廣人ID pdata.code = app.globalData.code;//獲取推廣人分享二維碼ID if (res.iv) { pdata.iv = encodeURI(res.iv); pdata.encryptedData = res.encryptedData; pdata.session_key = session_key; //獲取用戶信息生成訪問token app.basePost(app.U({ c: "login", a: "index" }), { info: pdata},function(res){ if (res.data.status == 0) return app.Tips( { title: "抱歉,您已被禁止登錄!" }, { tab: 4, url: "/pages/login-status/login-status" } ); else if(res.data.status==410){ wx.removeStorage({ key:"session_key"}); wx.hideLoading(); if (that.data.iShidden == true) that.setData({ iShidden: false }); return false; } //取消登錄提示 wx.hideLoading(); //關(guān)閉登錄彈出窗口 that.setData({ iShidden: true, ErrorCount:0}); //保存token和記錄登錄狀態(tài) app.globalData.token = res.data.token; app.globalData.isLog = true; //執(zhí)行登錄完成回調(diào) that.triggerEvent("onLoadFun", app.globalData.uid); //監(jiān)聽登錄狀態(tài) that.WatchIsLogin(); },function(res){ wx.hideLoading(); return app.Tips({title:res.msg}); }); } else { wx.hideLoading(); return app.Tips({ title: "用戶信息獲取失敗!"}); } }, fail: function () { wx.hideLoading(); that.setData({ iShidden: false }); }, }) }
第四步:監(jiān)聽登錄狀態(tài)
再服務(wù)器無法獲取到token時,當(dāng)前頁面會一直監(jiān)聽token是否為空,防止無限獲取token設(shè)置錯誤次數(shù),終止監(jiān)聽
監(jiān)聽token的用意為:token是服務(wù)器返回當(dāng)前用戶的訪問憑證,憑證有過期的時候這時候所有的網(wǎng)絡(luò)請求將無法訪問,所以用了一個愚蠢的方法來監(jiān)聽token
//監(jiān)聽登錄狀態(tài) WatchIsLogin:function(){ this.data.cloneIner=setInterval(function(){ //防止死循環(huán),超過錯誤次數(shù)終止監(jiān)聽 if (this.getErrorCount()) return clearInterval(this.data.clearInterval); if (app.globalData.token == "") this.setAuthStatus(); }.bind(this),800); this.setData({ cloneIner:this.data.cloneIner}); } /** * 處理錯誤次數(shù),防止死循環(huán) * */ setErrorCount:function(){ if (!this.data.ErrorCount) this.data.ErrorCount=1; else this.data.ErrorCount++; this.setData({ ErrorCount: this.data.ErrorCount}); }, /** * 獲取錯誤次數(shù),是否終止監(jiān)聽 * */ getErrorCount:function(){ return this.data.ErrorCount >= 10 ? true : false; }
以上就是組件內(nèi)全部的方法需要在組件生命周期函數(shù)內(nèi)調(diào)用第一步的方法檢測授權(quán),執(zhí)行登錄
attached(){ this.setAuthStatus(); }
注:在網(wǎng)絡(luò)請求中一定要處理token失效的操作,主要把 app.globalData.token和app.globalData.isLog 設(shè)置回空和false
這里附上沒有定義的一些app內(nèi)公用的快捷方法以下的方法最好是寫在其他文件里面在app.js里面寫一個快捷調(diào)用的方法
/* * post網(wǎng)絡(luò)請求 * @param string | object 請求地址 * @param object data POST請求數(shù)組 * @param callable successCallback 成功執(zhí)行方法 * @param callable errorCallback 失敗執(zhí)行方法 */ const basePost = function (url, data, successCallback, errorCallback, header) { if (typeof url == "object") url = U(url); wx.request({ url: url, data: data, dataType : "json", method: "POST", header: header, success: function (res) { try{ if (res.data.code == 200) { successCallback && successCallback(res.data); } else { if (res.data.code == 402) getApp().globalData.token = "", getApp().globalData.isLog = false; //返回狀態(tài)為401時,用戶被禁止訪問 關(guān)閉當(dāng)前所有頁面跳轉(zhuǎn)至用戶禁止登錄頁面 if (res.data.code == 401) return Tips({ title: res.data.msg}, { tab: 4, url:"/pages/login-status/login-status"}); errorCallback && errorCallback(res.data); } } catch (e) { console.log(e); } }, fail: function (res) { errorCallback && errorCallback(res); }, complete: function (res) { } }); }
/* * 組裝URl *@param object opt */ const U = function (opt, url) { var m = opt.m || "routine_two", c = opt.c || "auth_api", a = opt.a || "index", q = opt.q || "", p = opt.p || {}, params = "", gets = ""; if (url == undefined) url=getApp().globalData.url; params = Object.keys(p).map(function (key) { return key + "/" + p[key]; }).join("/"); gets = Object.keys(q).map(function (key) { return key + "=" + q[key]; }).join("&"); return url + "/" + m + "/" + c + "/" + a + (params == "" ? "" : "/" + params) +".html"+ (gets == "" ? "" : "?" + gets); }
代碼量有點多,都是能用到的,望大神們多多指點
本小程序后臺框架由 http://github.crmeb.net/u/blue 提供
TP5+EasyWeChat技術(shù)支持
如果對微信小程序授權(quán)不熟悉的可以用 EasyWeChat,確實好用;不是來吹這個EasyWeChat來了,只是個人覺得好用勿噴
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31558.html
摘要:傳統(tǒng)的網(wǎng)頁編程采用的三劍客來實現(xiàn),在微信小程序中同樣有三劍客。觀察者模式不難實現(xiàn),重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統(tǒng)的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權(quán)網(wǎng)易云社區(qū)發(fā)布。 簡介為了更好的展示我們即時通訊SDK強悍的能力,網(wǎng)易云信IM SDK微信小程序DEMO的開發(fā)就提上了日程。用產(chǎn)品的話說就是: 云信 IM 小程序 S...
摘要:二開發(fā)工具與資源平臺微信開發(fā)者工具主要用于敲網(wǎng)頁代碼,但是最主要用來進(jìn)行網(wǎng)頁效果預(yù)覽。八總結(jié)以上微信小程序旨在實現(xiàn)一些基本功能,也存在一些不合理之處,如對項目有疑問或不同見解的同仁可與本人聯(lián)系郵箱。 一、引言 相信各位碼農(nóng)們都有過要調(diào)用各大資源網(wǎng)站提供的API的經(jīng)歷,但是在接入的時候出現(xiàn)許多這樣那樣的問題,最近在做一個業(yè)界備受關(guān)注的微信小程序項目,使用了多個網(wǎng)站的API接入,接...
摘要:優(yōu)雅解決微信小程序授權(quán)登錄需要觸發(fā)聊一聊最近的一個項目,這個項目是一個收書售書的小程序,有商城專欄信息發(fā)布論壇等功能。微信不會把的有效期告知開發(fā)者。 優(yōu)雅解決微信小程序授權(quán)登錄需要button觸發(fā) 聊一聊最近的一個項目,這個項目是一個收書、售書的小程序,有商城、專欄、信息發(fā)布論壇等功能。雖然不是面向所有用戶,但要求無論用戶是否授權(quán)都皆可使用,但同時也要求部分功能對不授權(quán)的用戶限制開放。...
摘要:除官方外的參考文章微信小程序?qū)嵗齽?chuàng)建下發(fā)模板消息實例手把手教你開發(fā)微信小程序之模版消息開發(fā)教你突破小程序模板消息的推送限制獲取用戶信息接口的廢棄問題接口是獲取用戶信息昵稱,頭像等的接口,在官方文檔上寫是即將廢棄。 ----------------更新-------------- 2018年10月10日官網(wǎng)3個接口廢棄的通知: 1、分享監(jiān)聽接口分享消息給好友時,開發(fā)者將無法從callba...
摘要:在小程序啟動的時候自動登錄,目前沒獲取用戶信息,所以不需要用戶授權(quán),這個邏輯放在根目錄下的的方法中。做完之后發(fā)現(xiàn)了一個很嚴(yán)重的問題,就是的方法確實會在小程序啟動的時候執(zhí)行,但是首頁也會是在文件的中第一個頁面也會同時執(zhí)行,它不是阻塞的。 啟動頁在APP中是個很常見的需求,為什么對于小程序來說也非常重要呢?首先我描述一下我在開發(fā)過程中遇到的一些問題以及解決的步驟,到最后為什么要加啟動頁,看...
閱讀 3021·2021-10-27 14:15
閱讀 3014·2021-09-07 10:18
閱讀 1332·2019-08-30 15:53
閱讀 1584·2019-08-26 18:18
閱讀 3385·2019-08-26 12:15
閱讀 3468·2019-08-26 10:43
閱讀 662·2019-08-23 16:43
閱讀 2218·2019-08-23 15:27