您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關怎么在微信小程序中實現非跳轉式組件授權登錄,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
大致邏輯:授權 -> 發送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); }
上述就是小編為大家分享的怎么在微信小程序中實現非跳轉式組件授權登錄了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。