怎么在微信小程序中實(shí)現(xiàn)非跳轉(zhuǎn)式組件授權(quán)登錄

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)怎么在微信小程序中實(shí)現(xiàn)非跳轉(zhuǎn)式組件授權(quán)登錄,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比山海關(guān)網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式山海關(guān)網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋山海關(guān)地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。

大致邏輯:授權(quán) -> 發(fā)送code到服務(wù)器獲取session_key - > 保存在小程序緩存內(nèi) -> 調(diào)用wx.getUserInfo和session_key獲取用戶信息 -> 登錄成功返回訪問(wèn)token -> 記錄登錄狀態(tài) -> 執(zhí)行登錄成功監(jiān)聽(tīng)(失敗則不監(jiān)聽(tīng))

直接上代碼,一下均為小程序組件模式有興趣的可以看下官方文檔

創(chuàng)建components(自定義名稱)文件夾pages文件夾同級(jí)主要放置組件文件

創(chuàng)建 authorize (自定義名稱)文件夾 還是一樣的創(chuàng)建 對(duì)應(yīng)的authorize.js ,authorize.wxml .authorize.wxss,authorize.json特別注意這里的 authorize.json 文件里面要定義當(dāng)前頁(yè)面為組件

{

"component": true
}

到這里準(zhǔn)備工作完成

authorize.js 換成組件的寫(xiě)法,具體參考小程序官方文檔,這里展示我定義的

Component({
  //組件的對(duì)外屬性 說(shuō)的確實(shí)很官方,用過(guò)vue組件的就很容易理解這點(diǎn)
  //父級(jí)向子級(jí)傳值這里就是接收值得地方
 properties:{
   //名稱要和父級(jí)綁定的名稱相同
   //這里主要是控制自動(dòng)授權(quán)彈框是否顯示 true=隱藏 false=顯示
  iShidden:{
   type:Boolean,//定義類(lèi)型
   value: true,//定義默認(rèn)值
  },
  //是否自動(dòng)登錄 這里主要用于沒(méi)有授權(quán)是否自動(dòng)彈出授權(quán)提示框 
  //**用在不自動(dòng)登錄頁(yè)面但是某些操作需要授權(quán)登錄**
  isAuto:{
   type: Boolean,
   value: true,
  },
 },
 //組件的內(nèi)部數(shù)據(jù),和 properties 一同用于組件的模板渲染
 data:{
  cloneIner:null
 },
 //組件所在頁(yè)面的生命周期聲明對(duì)象
 pageLifetimes:{
   //頁(yè)面隱藏
   hide:function(){
   //關(guān)閉頁(yè)面時(shí)銷(xiāo)毀定時(shí)器
   if(this.data.cloneIner) clearInterval(this.data.clearInterval);
  },
  //頁(yè)面打開(kāi)
  show:function(){
   //打開(kāi)頁(yè)面銷(xiāo)毀定時(shí)器
   if (this.data.cloneIner) clearInterval(this.data.clearInterval);
  },
 },
 //組件生命周期函數(shù),在組件實(shí)例進(jìn)入頁(yè)面節(jié)點(diǎn)樹(shù)時(shí)執(zhí)行
 attached(){
   
 },
 //組件的方法 
 methods:{
 
 }
 });

注:以下的方法都需寫(xiě)在 methods 內(nèi)

第一步:未授權(quán)用戶判斷是否執(zhí)行授權(quán)還是直接進(jìn)行獲取用戶信息

//檢測(cè)登錄狀態(tài)并執(zhí)行自動(dòng)登錄
  setAuthStatus(){
   var that = this;
   that.setErrorCount();
   wx.getSetting({
    success(res) {
    //這里會(huì)檢測(cè)是否授權(quán),如果授權(quán)了會(huì)直接調(diào)用自動(dòng)登錄
     if (!res.authSetting['scope.userInfo']) {
      //沒(méi)有授權(quán)不會(huì)自動(dòng)彈出登錄框
      if (that.data.isAuto === false) return; 
      //自動(dòng)彈出授權(quán) 
      that.setData({ iShidden: false });
     } else {
      //自動(dòng)登錄
      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();
      }
     }
    }
   })
  }

第二步,沒(méi)有授權(quán)執(zhí)行打開(kāi)授權(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,如果沒(méi)有則請(qǐng)求服務(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èn)服務(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 登錄獲取訪問(wèn)權(quán)限

getUserInfoBydecryptCode: function () {
   var that = this;
   var session_key = wx.getStorageSync('session_key')
   //沒(méi)有獲取到session_key,打開(kāi)授權(quán)頁(yè)面
   //這里必須的判斷存在緩存中的session_key是否存在,因?yàn)樵诘谝徊降臅r(shí)候,判斷了
   //授權(quán)了將自動(dòng)執(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;
      //獲取用戶信息生成訪問(wèn)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īng)登錄狀態(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īng)登錄狀態(tài)

再服務(wù)器無(wú)法獲取到token時(shí),當(dāng)前頁(yè)面會(huì)一直監(jiān)聽(tīng)token是否為空,防止無(wú)限獲取token設(shè)置錯(cuò)誤次數(shù),終止監(jiān)聽(tīng)

監(jiān)聽(tīng)token的用意為:token是服務(wù)器返回當(dāng)前用戶的訪問(wèn)憑證,憑證有過(guò)期的時(shí)候這時(shí)候所有的網(wǎng)絡(luò)請(qǐng)求將無(wú)法訪問(wèn),所以用了一個(gè)愚蠢的方法來(lái)監(jiān)聽(tīng)token

//監(jiān)聽(tīng)登錄狀態(tài)
  WatchIsLogin:function(){
   this.data.cloneIner=setInterval(function(){
    //防止死循環(huán),超過(guò)錯(cuò)誤次數(shù)終止監(jiān)聽(tīng)
    if (this.getErrorCount()) return clearInterval(this.data.clearInterval);
    if (app.globalData.token == '') this.setAuthStatus();
   }.bind(this),800);
   this.setData({ cloneIner:this.data.cloneIner});
  }
 /**
   * 處理錯(cuò)誤次數(shù),防止死循環(huán)
   * 
  */
  setErrorCount:function(){
   if (!this.data.ErrorCount) this.data.ErrorCount=1;
   else this.data.ErrorCount++;
   this.setData({ ErrorCount: this.data.ErrorCount});
  },
  /**
   * 獲取錯(cuò)誤次數(shù),是否終止監(jiān)聽(tīng)
   * 
  */
  getErrorCount:function(){
   return this.data.ErrorCount >= 10 ? true : false;
  }

以上就是組件內(nèi)全部的方法需要在組件生命周期函數(shù)內(nèi)調(diào)用第一步的方法檢測(cè)授權(quán),執(zhí)行登錄

 attached(){
  this.setAuthStatus();
 }

注:在網(wǎng)絡(luò)請(qǐng)求中一定要處理token失效的操作,主要把 app.globalData.token和app.globalData.isLog 設(shè)置回空和false

這里附上沒(méi)有定義的一些app內(nèi)公用的快捷方法以下的方法最好是寫(xiě)在其他文件里面在app.js里面寫(xiě)一個(gè)快捷調(diào)用的方法

/*
* post網(wǎng)絡(luò)請(qǐng)求 
* @param string | object 請(qǐng)求地址
* @param object data POST請(qǐng)求數(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時(shí),用戶被禁止訪問(wèn) 關(guān)閉當(dāng)前所有頁(yè)面跳轉(zhuǎn)至用戶禁止登錄頁(yè)面
     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);
}

上述就是小編為大家分享的怎么在微信小程序中實(shí)現(xiàn)非跳轉(zhuǎn)式組件授權(quán)登錄了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享題目:怎么在微信小程序中實(shí)現(xiàn)非跳轉(zhuǎn)式組件授權(quán)登錄
當(dāng)前網(wǎng)址:http://muchs.cn/article34/gepjse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)建站公司、自適應(yīng)網(wǎng)站、網(wǎng)站導(dǎo)航、動(dòng)態(tài)網(wǎng)站定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開(kāi)發(fā)