#聊聊微信小程式使用者授權登入,無感知登入,強制授權~~~

wuliDream發表於2018-02-11
#直接貼程式碼,複製可用哦。。。上乾貨

//app.js
App({
  setConfig: {            //一些配置資料
    url:  '',             //配置請求地址的baseUrl
    requestConfig:{       //自己封裝了個request 處理一些共用的拋錯toast ,requestConfig是app.request裡的引數,配置些預設引數
      data:{},
      token:"",           //在小程式授權後,本教程基於token處理使用者登入憑證
      type:"POST",
      callback:function(){},
      failCb:function(){}
    }
  },
  globalData: {          // 小程式推薦全域性共用的資料,存在 globalData裡
    userInfo: null,
    token:''
  },
  onLaunch: function () {
    this.userLogin();    // 呼叫登入方法,處理登入
  },
  //登入
  userLogin: function(callback){  //callback是使用者授權登入後的一些回撥函式
    var that = this;
    //獲取登入code
    wx.login({           // 小程式登入介面,成功後拿到code 到後臺換取 openId, sessionKey, unionId
      success: function (res) {
        if (res.code) {
          var codes = res.code;
          //獲取使用者資訊  // 因為 我們程式 要收集使用者頭像,暱稱等,有一套使用者體系
          wx.getSetting({ //先呼叫getSetting 拿到使用者已經授權的一些列表,如果已經授權 再後面程式碼 就無需再wx.authorize 授權
            success: res => {
              if (res.authSetting['scope.userInfo']) {      // 使用者資訊已經授權過,
                // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框
                callback?(that.getUserInfoHandle(codes,callback)): (that.getUserInfoHandle(codes));     //getUserInfoHandle 方法是處理使用者資訊,提取出來
              }else{
                wx.authorize({                             // 如果在那使用者授權資訊的時候 沒有拿到,則呼叫wx.authorize 授權,拿使用者userInfo
                  scope: 'scope.userInfo',
                  success: res => {
                    //使用者已經同意小程式授權
                    callback?(that.getUserInfoHandle(codes,callback)): (that.getUserInfoHandle(codes));  //同上
                  },
                  fail: (e) =>{                            //如果使用者點選拒絕授權,則呼叫wx.openSetting 調起客戶端小程式設定介面,返回使用者設定的操作結果。在這邊做了個封裝
                    that.openSetting()                     
                  }
                })
              }
            }
          });
        } else {
          that.userLogin();                                 //登入失敗的話 ,重新呼叫 登入方法
          return false;
        }
      }
    })
  },
  //getUserInfo
  getUserInfoHandle: function (codes,callback){         // codes是wx.login 後拿到的code,callback是登入成功的回撥函式
    var that = this;
    wx.getUserInfo({                                    // 獲取使用者資訊
      success: res => {
        // 可以將 res 傳送給後臺解碼出 unionId
        that.globalData.userInfo  = res.userInfo;       // 存在全域性 之後供各個page拿資料
        // 所以此處加入 callback 以防止這種情況
        if (that.userInfoReadyCallback) {               // userInfoReadyCallback是個回撥函式 由於wx.getUserInfo 是非同步的,當各個page需要userInfo資訊時,先判斷全域性userInfo是否有資訊,沒有則定義個回撥app.userInfoReadyCallback 自己傳個回撥函式,才能拿到userInfo資料
          that.userInfoReadyCallback(res)
        }
        //使用者資訊入庫
        var url = that.setConfig.url + '/login';        // 拿到資訊後 ,呼叫登入介面
        var data = {                                    // 登入介面 需要的資料
          code: codes,
          encryptedData: res.encryptedData,             // 這個引數和下面那個引數  我們沒有直接將使用者頭像,暱稱傳遞,防止資料篡改,採用加密的方式 ,後端再解密拿到使用者資訊 詳情請看官方文件
          iv: res.iv 
        }
        callback?that.request({url, data},callback):that.request({url, data});      //登入請求
      }
    })
  },
  //openSetting
  openSetting:function(){                               
    var that = this;
    wx.showModal({                                    // modal 提示使用者
      title: '提示',
      content: '小程式需要獲取使用者資訊許可權,點選確認。前往設定或退出程式?',
      showCancel:false,
      success: function(res) {              
        wx.openSetting({                              // 調起客戶端小程式設定介面
          success: (res) => {
            var userInfoFlag = res.authSetting['scope.userInfo'];    //拿到使用者操作結果
            if(!userInfoFlag){                        // 如果使用者沒有點開同意使用者授權 ,則再呼叫openSetting 彈框提示,總之 同意了 才會關閉modal 進入我們小程式
              that.openSetting();
            }else{
              that.userLogin();                       // 使用者成功設定授權後,再呼叫登入方法 ,給到後臺 拿使用者資訊 等操作
            }
          }
        })
      }
    })
  },
  //資料互動
  request: function (opts,loginCb){
    let {url,data,token,callback,type,failCb}= {...this.setConfig.requestConfig,...opts}
    var that = this;
    //發起網路請求
    wx.request({
      url: url,
      data: data, 
      method:type,
      header: { 
        'content-type': 'application/x-www-form-urlencoded',
        'token':token||that.globalData.token       //每次請求都帶token,進行使用者認證
      },
      success:function(res){
        //根據全域性做處理
        var status = ''+res.statusCode;
        var firstStatus = status[0];
        switch (firstStatus){
          case '2':
          case '3':
            if(res.data.err_code){
              wx.hideLoading();
              wx.showToast({
                title: res.data.err_msg,
                icon:'none',
                mask: true,
                duration: 1500
              })
              if(res.data.err_code == '1'){  //沒有登陸的錯誤碼 重新登陸
                that.userLogin();
              }
              return false;
            }
            if(url.indexOf('/login')>-1){    //登陸介面 返回token,存在全域性globalData中
              if (res.data.result){
                that.globalData.token = res.data.result.token;
              }
            }
            callback(res);                  // 成功後大回撥函式
            break;
          case '4':
            wx.showToast({
              title:'客戶端錯哦~',
              mask:true,
              icon:'none',
              duration:1500
            })
            break;
          case '5':
            wx.showToast({
              title:'服務端錯誤哦~',
              mask:true,
              icon:'none',
              duration:1500
            })     
            break; 
          default:
            break;
        }
      },
      fail:function(e){
        wx.showToast({
          title:'當前網路狀態不佳,請稍後再試',
          mask:true,
          icon:'none',
          duration:1500
        })
        failCb&&failCb(e);
      }
    })
  }
})
複製程式碼



相關文章