摘要:首先附上官方文檔地址和授權流程官方地址流程圖大致邏輯授權發送到服務器獲取保存在小程序緩存內調用和獲取用戶信息登錄成功返回訪問記錄登錄狀態執行登錄成功監聽失敗則不監聽直接上代碼,一下均為小程序組件模式有興趣的可以看下官方文檔創建自
首先附上官方文檔地址和授權流程
官方地址:https://developers.weixin.qq....
流程圖:
大致邏輯:授權 -> 發送code到服務器獲取session_key - > 保存在小程序緩存內 -> 調用wx.getUserInfo和session_key獲取用戶信息 -> 登錄成功返回訪問token -> 記錄登錄狀態 -> 執行登錄成功監聽(失敗則不監聽)
直接上代碼,一下均為小程序組件模式有興趣的可以看下官方文檔
創建components(自定義名稱)文件夾pages文件夾同級主要放置組件文件
創建 authorize (自定義名稱)文件夾 還是一樣的創建 對應的authorize.js ,authorize.wxml .authorize.wxss,authorize.json特別注意這里的 authorize.json 文件里面要定義當前頁面為組件
{
"component": true
}
到這里準備工作完成
authorize.js 換成組件的寫法,具體參考小程序官方文檔,這里展示我定義的
Component({ //組件的對外屬性 說的確實很官方,用過vue組件的就很容易理解這點 //父級向子級傳值這里就是接收值得地方 properties:{ //名稱要和父級綁定的名稱相同 //這里主要是控制自動授權彈框是否顯示 true=隱藏 false=顯示 iShidden:{ type:Boolean,//定義類型 value: true,//定義默認值 }, //是否自動登錄 這里主要用于沒有授權是否自動彈出授權提示框 //**用在不自動登錄頁面但是某些操作需要授權登錄** isAuto:{ type: Boolean, value: true, }, }, //組件的內部數據,和 properties 一同用于組件的模板渲染 data:{ cloneIner:null }, //組件所在頁面的生命周期聲明對象 pageLifetimes:{ //頁面隱藏 hide:function(){ //關閉頁面時銷毀定時器 if(this.data.cloneIner) clearInterval(this.data.clearInterval); }, //頁面打開 show:function(){ //打開頁面銷毀定時器 if (this.data.cloneIner) clearInterval(this.data.clearInterval); }, }, //組件生命周期函數,在組件實例進入頁面節點樹時執行 attached(){ }, //組件的方法 methods:{ } });
注:以下的方法都需寫在 methods 內
第一步:未授權用戶判斷是否執行授權還是直接進行獲取用戶信息
//檢測登錄狀態并執行自動登錄 setAuthStatus(){ var that = this; that.setErrorCount(); wx.getSetting({ success(res) { //這里會檢測是否授權,如果授權了會直接調用自動登錄 if (!res.authSetting["scope.userInfo"]) { //沒有授權不會自動彈出登錄框 if (that.data.isAuto === false) return; //自動彈出授權 that.setData({ iShidden: false }); } else { //自動登錄 that.setData({ iShidden: true }); if (app.globalData.token) { //這里是授權回調 that.triggerEvent("onLoadFun", app.globalData.token); that.WatchIsLogin(); } else { wx.showLoading({ title: "正在登錄中" }); //這里是已授權調用wx.getUserInfo that.getUserInfoBydecryptCode(); } } } }) }
第二步,沒有授權執行打開授權彈出框
//授權 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,如果沒有則請求服務器再次緩存 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); } }); }, //訪問服務器獲得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失敗" }); }); }
第三步:執行getUserInfoBydecryptCode 登錄獲取訪問權限
getUserInfoBydecryptCode: function () { var that = this; var session_key = wx.getStorageSync("session_key") //沒有獲取到session_key,打開授權頁面 //這里必須的判斷存在緩存中的session_key是否存在,因為在第一步的時候,判斷了 //授權了將自動執行獲取用戶信息的方法 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(); //關閉登錄彈出窗口 that.setData({ iShidden: true, ErrorCount:0}); //保存token和記錄登錄狀態 app.globalData.token = res.data.token; app.globalData.isLog = true; //執行登錄完成回調 that.triggerEvent("onLoadFun", app.globalData.uid); //監聽登錄狀態 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 }); }, }) }
第四步:監聽登錄狀態
再服務器無法獲取到token時,當前頁面會一直監聽token是否為空,防止無限獲取token設置錯誤次數,終止監聽
監聽token的用意為:token是服務器返回當前用戶的訪問憑證,憑證有過期的時候這時候所有的網絡請求將無法訪問,所以用了一個愚蠢的方法來監聽token
//監聽登錄狀態 WatchIsLogin:function(){ this.data.cloneIner=setInterval(function(){ //防止死循環,超過錯誤次數終止監聽 if (this.getErrorCount()) return clearInterval(this.data.clearInterval); if (app.globalData.token == "") this.setAuthStatus(); }.bind(this),800); this.setData({ cloneIner:this.data.cloneIner}); } /** * 處理錯誤次數,防止死循環 * */ setErrorCount:function(){ if (!this.data.ErrorCount) this.data.ErrorCount=1; else this.data.ErrorCount++; this.setData({ ErrorCount: this.data.ErrorCount}); }, /** * 獲取錯誤次數,是否終止監聽 * */ getErrorCount:function(){ return this.data.ErrorCount >= 10 ? true : false; }
以上就是組件內全部的方法需要在組件生命周期函數內調用第一步的方法檢測授權,執行登錄
attached(){ this.setAuthStatus(); }
注:在網絡請求中一定要處理token失效的操作,主要把 app.globalData.token和app.globalData.isLog 設置回空和false
這里附上沒有定義的一些app內公用的快捷方法以下的方法最好是寫在其他文件里面在app.js里面寫一個快捷調用的方法
/* * post網絡請求 * @param string | object 請求地址 * @param object data POST請求數組 * @param callable successCallback 成功執行方法 * @param callable errorCallback 失敗執行方法 */ 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; //返回狀態為401時,用戶被禁止訪問 關閉當前所有頁面跳轉至用戶禁止登錄頁面 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技術支持
如果對微信小程序授權不熟悉的可以用 EasyWeChat,確實好用;不是來吹這個EasyWeChat來了,只是個人覺得好用勿噴
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31558.html
摘要:傳統的網頁編程采用的三劍客來實現,在微信小程序中同樣有三劍客。觀察者模式不難實現,重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權網易云社區發布。 簡介為了更好的展示我們即時通訊SDK強悍的能力,網易云信IM SDK微信小程序DEMO的開發就提上了日程。用產品的話說就是: 云信 IM 小程序 S...
摘要:二開發工具與資源平臺微信開發者工具主要用于敲網頁代碼,但是最主要用來進行網頁效果預覽。八總結以上微信小程序旨在實現一些基本功能,也存在一些不合理之處,如對項目有疑問或不同見解的同仁可與本人聯系郵箱。 一、引言 相信各位碼農們都有過要調用各大資源網站提供的API的經歷,但是在接入的時候出現許多這樣那樣的問題,最近在做一個業界備受關注的微信小程序項目,使用了多個網站的API接入,接...
摘要:優雅解決微信小程序授權登錄需要觸發聊一聊最近的一個項目,這個項目是一個收書售書的小程序,有商城專欄信息發布論壇等功能。微信不會把的有效期告知開發者。 優雅解決微信小程序授權登錄需要button觸發 聊一聊最近的一個項目,這個項目是一個收書、售書的小程序,有商城、專欄、信息發布論壇等功能。雖然不是面向所有用戶,但要求無論用戶是否授權都皆可使用,但同時也要求部分功能對不授權的用戶限制開放。...
摘要:除官方外的參考文章微信小程序實例創建下發模板消息實例手把手教你開發微信小程序之模版消息開發教你突破小程序模板消息的推送限制獲取用戶信息接口的廢棄問題接口是獲取用戶信息昵稱,頭像等的接口,在官方文檔上寫是即將廢棄。 ----------------更新-------------- 2018年10月10日官網3個接口廢棄的通知: 1、分享監聽接口分享消息給好友時,開發者將無法從callba...
摘要:在小程序啟動的時候自動登錄,目前沒獲取用戶信息,所以不需要用戶授權,這個邏輯放在根目錄下的的方法中。做完之后發現了一個很嚴重的問題,就是的方法確實會在小程序啟動的時候執行,但是首頁也會是在文件的中第一個頁面也會同時執行,它不是阻塞的。 啟動頁在APP中是個很常見的需求,為什么對于小程序來說也非常重要呢?首先我描述一下我在開發過程中遇到的一些問題以及解決的步驟,到最后為什么要加啟動頁,看...
閱讀 3011·2021-10-27 14:15
閱讀 2999·2021-09-07 10:18
閱讀 1320·2019-08-30 15:53
閱讀 1570·2019-08-26 18:18
閱讀 3373·2019-08-26 12:15
閱讀 3460·2019-08-26 10:43
閱讀 654·2019-08-23 16:43
閱讀 2207·2019-08-23 15:27