小程序微信登錄

相信大家做小程序的乡话, 對(duì)微信登錄的機(jī)制都有一定的了解以及想法了摧玫;
大家八仙過海 各顯神通,下面這篇文章,只是我對(duì)其的了解
如果大家有好的想法 N芟瘛N萑骸!請(qǐng)一定 與 我交流;的印I瞩铩!

I降狠、處理登錄的邏輯

關(guān)于會(huì)遇到的問題以及處理

  1. 首先請(qǐng)求是個(gè)異步事件对竣,我們并不是所有接口都需要登錄;
    既然是異步事件榜配, 那么我們肯定要在回調(diào)函數(shù)中進(jìn)行處理
    這樣的話就要涉及到wx.request的封裝否纬;我們?cè)谙旅嬷v
  2. 關(guān)于code的獲取
    登錄需要用戶點(diǎn)擊微信自帶的button才能獲取到
    <button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" 
    type="warn" size="default" loading="{{loading}}" bindtap="primary"> 
        一鍵登錄 
    </button>
  1. 關(guān)于權(quán)限判斷,以及如何判斷
    咱們不能所有接口都需要登錄蛋褥, 那樣的話連審核都過不了临燃;
    這里同樣需要對(duì)wx.requesrt進(jìn)行封裝;下面講

  2. 登錄的處理邏輯圖:

    小程序登錄邏輯.png

II烙心、wx.request的封裝邏輯

1. wx.request的封裝

  1. 基礎(chǔ)層
    a. 調(diào)用擴(kuò)展層的處理函數(shù)
    b. wx.request請(qǐng)求

  2. 擴(kuò)展層
    beforeRequest 發(fā)起請(qǐng)求之前 處理有無網(wǎng)絡(luò)狀態(tài)
    handleRequestInportData 處理請(qǐng)求參數(shù)
    showMask 處理遮罩層
    stopLoading 停止各種的loading
    handleResponse 處理返回結(jié)果 (在這里面處理是否跳轉(zhuǎn)登錄)

2. wx.request的封裝邏輯圖

小程序request請(qǐng)求封裝.png

III膜廊、關(guān)于登錄 對(duì)wx.request的封裝

當(dāng)然是寫在handleResponse里面的
跟后端約定好返回碼 做對(duì)應(yīng)的操作;
我們這邊規(guī)定 如果返回 code == 401 || code == 403的話就表示沒有登錄

if (res.data.code == '401' || res.data.code == '403') {
      console.error('沒登錄淫茵,去登錄溃论,并且設(shè)置狀態(tài)')
      // 清空之前的token
      wx.removeStorageSync('accessToken');      
      // 正在登錄中
      if (that.globalData.isLogging) return true;   
      // 沒在登錄中 進(jìn)入登錄狀態(tài),并且設(shè)置isLogging 
      that.globalData.isLogging = true;     
      // 登錄失效且不在白名單 
      if (!CONFIG['API_WHITE_LIST'].includes(thisUrl)) {
        // 跳到登錄
        let pages = getCurrentPages();
        for (let i in pages) {
          if (pages[i].route == '/pages/login/login') {
            // console.log(i)
            wx.navigateBack({
              delta: pages.length - (i + 1)
            })
            return true;
          }
        }
        wx.navigateTo({ url: '/pages/login/login' });
        return true;
      }
      return;
    }

IV痘昌、相關(guān)代碼

1. wx.request關(guān)于基礎(chǔ)層的封裝

// 基礎(chǔ)層: 
  // 基于微信的request進(jìn)行二次封裝,myRequest是基礎(chǔ)層
  // beforeRequest 處理有無網(wǎng)絡(luò)狀態(tài)
  // handleRequestInportData 處理請(qǐng)求參數(shù)
  // showMask 處理遮罩層
  // stopLoading 停止各種的loading
  // handleResponse 處理返回結(jié)果
  
  myRequest: function (url, data, methods, callback, loadType, errorFun, headers) {
    let _this = this;
    // 檢查是擁有網(wǎng)絡(luò) 沒有網(wǎng)絡(luò) 就return炬转;
    if (_this.beforeRequest(url)) return;
    // 參數(shù)處理
    let theData = this.handleRequestInportData(url, data, methods, callback, loadType, errorFun, headers, _this);
    // 處理遮罩層
    this.showMask(theData.loadType);

    // 是否是啟用模擬數(shù)據(jù)
    if (DEBUG) {
      let responseData = myData.getData(url, data);
      setTimeout(() => {
        console.log('DEBUG response : ')
        console.log(responseData.data)
        _this.stopLoading();
        callback(responseData)
        // _this.handleResponse(responseData, theData);
      }, 800)
    }else{
    // 開始請(qǐng)求
      wx.request({
        url: theData.url,
        data: {
          ...theData.data,
          ..._this.globalData.otherParams
        },
        method: theData.methods,
        header: theData.headers,
        success: function (res) {
          // 處理返回結(jié)果
          _this.handleResponse(res, theData, _this, url);
        },
        fail: function (err) {
          _this.stopLoading();
        },
        complete: function () {
        }
      })
    }
    // 請(qǐng)求結(jié)束
  },

2. wx.request 擴(kuò)展層的封裝


// 在請(qǐng)求發(fā)起之前需要做的事情 處理有無網(wǎng)絡(luò)狀態(tài)
  beforeRequest: function(tempUrl) {
    let _this = this;
    wx.getNetworkType({
      success: function (res) {
        if (res.networkType == 'none') {
          return true;
        }
      }
    })
  },

  // 處理請(qǐng)求參數(shù):
  handleRequestInportData: (
    url,
    data,
    methods = 'post',
    callback = () => console.log('未傳入回調(diào)callback'),
    loadType = 'mask',
    errorFun = (err) => {
      wx.hideLoading();
      wx.showToast({
        title: err.message,
        icon: 'none',
        mask: true,
        duration: 2000
      })
      console.log('未傳入回調(diào) errorFun')
    },
    headers = {},
    that
  ) => {
    let requestData = {};
    if (!url) {
      console.error('傳入myRequest的URL不可為空');
      return;
    }
    headers = {
      'content-type': 'application/json',
      'Authorization': 'Bearer ' + that.globalData.accessToken,
      'enctype': 'raw'
    }
    data.referrer_uid = that.globalData.referrer_uid != 0 ? that.globalData.referrer_uid : 0;

    requestData.url = InterFace[url];
    requestData.data = data;
    requestData.methods = methods;
    requestData.callback = callback;
    requestData.loadType = loadType;
    requestData.errorFun = errorFun;
    requestData.headers = headers;
    return requestData;
  },



  // 處理返回結(jié)果:
  handleResponse: (res, theData, that, tempUrl) => {
    let _this = this;
    that.stopLoading();
    if (res.data.code == '401' || res.data.code == '403') {
      console.error('沒登錄辆苔,去登錄,并且設(shè)置狀態(tài)')
      // console.error(that.globalData.isLogging)
      wx.removeStorageSync('accessToken');
      // 正在登錄中 設(shè)置 isLogging
      if (that.globalData.isLogging) return true;
      that.globalData.isLogging = true;
      // 登錄失效且不在白名單 !wx.getStorageSync('accessToken') && !API_WHITE_LIST.includes(tempUrl)
      if (!CONFIG['API_WHITE_LIST'].includes(tempUrl)) {
        // 跳到登錄
        let pages = getCurrentPages();
        // Tips: 判斷頁面棧中是否有l(wèi)ogin
        for (let i in pages) {
          if (pages[i].route == '/pages/login/login') {
            wx.navigateBack({
              delta: pages.length - (i + 1)
            })
            return true;
          }
        }
        wx.navigateTo({ url: '/pages/login/login' });
        return true;
      }
      return;
    }
    if (res.data.status == 200 && res.data.code != 0) {
      // 調(diào)用錯(cuò)誤處理函數(shù)
      theData.errorFun(res.data)
      return;
    } else if (res.data.code == '503' || res.data.code == '500') {
      // 故障頁面
      wx.reLaunch({
        url: '/pages/error/error'
      })
      return;
    }
    // 正常情況下扼劈, 回調(diào)
    if (res.data.status == 200 && res.data.code == 0) {
      theData.callback(res.data);
      return;
    }
  },


  // 展示遮罩層:
  showMask: (loadType) =>{
    if(loadType == 'none') return;
    if(loadType == 'top'){
      wx.showNavigationBarLoading()
      return;
    }
    wx.showLoading({
      title: '加載中',
      mask: true,
    })
  },
  

  /*
  * 停止各種loading狀態(tài)
  * @function stopLoading
  * @params {}
  * @barth {Constantine, 2017-11-13 17:19:15}
  */
  stopLoading: () => {
    wx.hideLoading();
    wx.hideNavigationBarLoading()
    wx.stopPullDownRefresh()
  },

3. 登錄頁面代碼

<!--pages/login/login.wxml-->
<nav title="選擇登錄方式"></nav>
<view class='cul-null'>抱歉您還未登錄呢, 請(qǐng)點(diǎn)擊下方授權(quán)按鈕登錄</view>
<view class='cul-null'>以使用更多功能</view>

<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" type="warn" size="default" loading="{{loading}}" bindtap="primary"> 一鍵登錄 </button>
<button class='login-btn' plain="{{true}}" type="default" size="default" bindtap="jumpTo" data-url='/pages/loginOld/loginOld'> 手機(jī)登錄 </button>
// pages/login/login.js
   /**
   * 生命周期函數(shù)--監(jiān)聽頁面隱藏
   */
  onHide: function () {
    app.globalData.isLogging = false;
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽頁面卸載
   */
  onUnload: function () {
    app.globalData.isLogging = false;
  },
  
  // 發(fā)起登錄
  getUserInfo: function (e) {
    console.log(e)
    this.setData({
      loading: true
    })
    let encryptedData = e.detail.encryptedData;
    let iv = e.detail.iv;

    console.log('login in')
    let _this = this;

    wx.login({
      success: ret => {
        // 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
        var CODE = ret.code;
        app.globalData.otherParams.wxcode = ret.code;
        app.myRequest('login', {
          wxcode: CODE,
          info: e.detail.userInfo,
          allInfo: e.detail,
        },
          'get',
          function (data) {
            console.log(data)
            if(data.data.has_reg == false){
              _this.userRegister(encryptedData, iv, data.data.openid)
              console.error('沒有注冊(cè)過')
            }else{
              console.error('注冊(cè)過')
              wx.showToast({
                title: '已有賬號(hào),登錄中',
                icon: 'none',
                mask: true,
                duration: 1500
              })
              _this.saveData(data);
              _this.setData({
                loading: false,
                userInfo: data.data.memberProfile,
                hasUserInfo: true
              })
              if (!data.data.has_phone){
                // TODO: 判斷用戶有沒有手機(jī)號(hào)悬荣,沒有調(diào)用接口綁定入撒,并且完善密碼
              }
              setTimeout(() => {
                wx.navigateBack({
                  delta: 1
                })
              }, 800)
            }
          })
        console.log('login', ret)
      }
    })
  },

  // 自動(dòng)注冊(cè)
  userRegister: function (encryptedData, iv, openid) {

    let _this = this;
    app.myRequest('userRegister', {
      encryptedData: encryptedData,
      iv: iv,
      openid: openid
    },
      'post',
      function (data) {
        console.log(data)
        // 緩存數(shù)據(jù)
        _this.saveData(data);
        _this.setData({
          userInfo: data.data.memberProfile,
          member: data.data.member,
          hasUserInfo: true,
          hideBindBlock: false,
          loading: false
        })
        app.globalData.newUser = true;
        wx.showToast({
          title: '注冊(cè)成功',
          icon: 'none',
          mask: true,
          duration: 1500
        })
      })
  },

4.關(guān)于登錄按鈕的樣式

不滿意的話你可以讓微信自帶的buttom opacity = 0
然后自己寫一個(gè)想要的樣式放在自帶的buttom的下面

結(jié)束語

能堅(jiān)持到這里的已經(jīng)是真愛了
希望各位大神 有好的方法 與我交流??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市先煎,隨后出現(xiàn)的幾起案子贼涩,更是在濱河造成了極大的恐慌,老刑警劉巖薯蝎,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遥倦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡占锯,警方通過查閱死者的電腦和手機(jī)袒哥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門缩筛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人堡称,你說我怎么就攤上這事瞎抛。” “怎么了却紧?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵桐臊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我啄寡,道長(zhǎng)豪硅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任挺物,我火速辦了婚禮懒浮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘识藤。我一直安慰自己砚著,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布痴昧。 她就那樣靜靜地躺著稽穆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赶撰。 梳的紋絲不亂的頭發(fā)上舌镶,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音豪娜,去河邊找鬼餐胀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瘤载,可吹牛的內(nèi)容都是我干的否灾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸣奔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼墨技!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挎狸,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤扣汪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后锨匆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體私痹,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紊遵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片账千。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖暗膜,靈堂內(nèi)的尸體忽然破棺而出匀奏,到底是詐尸還是另有隱情,我是刑警寧澤学搜,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布娃善,位于F島的核電站,受9級(jí)特大地震影響瑞佩,放射性物質(zhì)發(fā)生泄漏聚磺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一炬丸、第九天 我趴在偏房一處隱蔽的房頂上張望瘫寝。 院中可真熱鬧,春花似錦稠炬、人聲如沸焕阿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽暮屡。三九已至,卻和暖如春毅桃,著一層夾襖步出監(jiān)牢的瞬間褒纲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工钥飞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莺掠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓代承,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親渐扮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子论悴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容