微信小程序開發記錄(七)新版受權登陸的實現

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/wh_xmy/article/details/86475859javascript

背景:因爲微信官方修改了 getUserInfo、authorize 接口,沒法彈出受權窗口,因此如今沒法實現一進入微信小程序就彈出受權窗口,只能經過 button 去觸發,這樣就須要咱們加一個受權頁面去搞定了。php

前提:微信受權登陸僅適用於使用微信用戶信息的用戶,若是本身的項目有完善的用戶信息(一套式開發項目),可不使用微信用戶信息;若是僅爲微信小程序,則要受權、獲取用戶信息。java

實現思路:本身寫一個微信受權登陸頁面讓用戶實現點擊的功能,也就是實現了經過 button 組件去觸發 getUserInof 接口。在用戶進入微 信小程序的時候,判斷用戶是否受權了,若是沒有受權的話就顯示「受權頁面」,讓用戶去執行受權的操做。若是已經授了,則直接跳過這個頁面,進入首頁。數據庫

 

受權頁面的代碼:json

authorize.wxml小程序

<!--pages/authorize/authorize.wxml-->
<view class="box" wx:if="{{canIUse}}">
    <button class='bottom' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">
        容許受權
    </button>
</view>
 
<view class="box" wx:else>請升級微信版本</view>

  authorize.wxss微信小程序

/* pages/authorize/authorize.wxss */ page{ height:100%; width:100%; background: url(https://www.toread.com.cn/Public/sg/images/authorize.png) no-repeat 0 0;
  background-size:100% 100%; overflow: hidden; overflow-y: hidden; } .box{ height:100%; width:100%; padding-top:530rpx; box-sizing: border-box; } .bottom { box-sizing: border-box; border-radius: 8rpx; margin:0 34rpx; font-size: 36rpx; height:90rpx; font-family: PingFangHK-Regular; background:#ffffff; color:#000000; }

authorize.json緩存

{
  "navigationBarTitleText": "微信受權"
}

authorize.js服務器

// pages/authorize/authorize.js
// import util from './utils/util.js';
var app = getApp();
Page({
  /**
   * 頁面的初始數據
   */
  data: {
    //判斷小程序的API,回調,參數,組件等是否在當前版本可用。
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
 
  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function (options) {
    wx.hideShareMenu();//禁用分享功能
    var that = this;
    // 查看是否受權
    wx.getSetting({
      success: function (res) {
        if (res.authSetting['scope.userInfo']) {
          wx.getUserInfo({
            success: function (res) {
              //從數據庫獲取用戶信息
              // console.log(res);
              // that.queryUsreInfo();
              //用戶已經受權過
              wx.switchTab({
                url: '/pages/index/index'
              })
            }
          });
        }
      }
    })
  },
  // post請求
  requestData:function(url, data0, successCallback, errorCallback) {
    wx.request({
      url: app.globalData.rootApi + url,
      data: data0,
      method: "POST",
      success: function (res) {
        successCallback(res);
      },
      error: function (res) {
        errorCallback(res);
      },
    });
  },
  // 受權登陸
  login: function (data0, successCallback, errorCallback){
    this.requestData('Login/check', data0, successCallback, errorCallback);
  },
  //點擊受權按鈕
  bindGetUserInfo: function (e) {
    if (e.detail.userInfo) {
      //用戶按了容許受權按鈕
      var that = this;
      // 登陸
      wx.login({
        success: res => {
          // console.log(res);
          const code = res.code;
          // console.log(code);
          // 獲取用戶信息
          wx.getSetting({
            success: res => {
              if (res.authSetting['scope.userInfo']) {
                // 已經受權,能夠直接調用 getUserInfo 獲取頭像暱稱,不會彈框
                wx.getUserInfo({
                  success: res => {
                    // 能夠將 res 發送給後臺解碼出 
                    // console.log(res);
                    this.userInfo = res.userInfo;
                    var nickName = res.userInfo.nickName;
                    var avatarUrl = res.userInfo.avatarUrl;
                    // 存儲用戶名和頭像
                    wx.setStorageSync('nickName', nickName);
                    wx.setStorageSync('avatarUrl', avatarUrl);
                    var iv = res.iv;
                    var encryptedData = res.encryptedData;
                    var postData = {};
                    postData.code = code;
                    postData.iv = res.iv;
                    postData.encryptedData = res.encryptedData;
                    // console.log("postdata");
                    // console.log(postData);
                    app.globalData.userInfo = res.rawData;
                    //後臺服務器受權登陸接口
                    this.login(postData,
                      (res) => {
                        // console.log("login----")
                        if (res.data.code == 1) {//獲取成功 
                          // console.log("後臺服務器受權登陸成功!");
                          var utoken = res.data.utoken;
                          // 先移除可能須要更改的storage
                          // wx.removeStorageSync('utoken');
                          //設置本地緩存
                          wx.setStorage({
                            key: 'utoken',
                            data: utoken,
                          });
                          //用戶已經受權過
                          wx.reLaunch({
                            url: '/pages/index/index'
                          });
                        }
                   else {
                          wx.showModal({
                            title: '舒適提示',
                            content: res.data.msg
                          })
                        }
                      }
                    )
                    // 因爲 getUserInfo 是網絡請求,可能會在 Page.onLoad 以後才返回
                    // 因此此處加入 callback 以防止這種狀況
                    if (this.userInfoReadyCallback) {
                      this.userInfoReadyCallback(res)
                    }
                  }
                })
              }
            }
          })
        }
      })
    } else {
      //用戶按了拒絕按鈕
      wx.showModal({
        title: '警告',
        content: '您點擊了拒絕受權,將沒法進入小程序,請受權以後再進入!!!',
        showCancel: false,
        confirmText: '返回受權',
        success: function (res) {
          if (res.confirm) {
            // console.log('用戶點擊了「返回受權」')
          }
        }
      })
    }
  },
 
  /**
   * 生命週期函數--監聽頁面初次渲染完成
   */
  onReady: function () {
 
  },
 
  /**
   * 生命週期函數--監聽頁面顯示
   */
  onShow: function () {
 
  },
 
  /**
   * 生命週期函數--監聽頁面隱藏
   */
  onHide: function () {
 
  },
 
  /**
   * 生命週期函數--監聽頁面卸載
   */
  onUnload: function () {
 
  },
 
  /**
   * 頁面相關事件處理函數--監聽用戶下拉動做
   */
  onPullDownRefresh: function () {
 
  },
 
  /**
   * 頁面上拉觸底事件的處理函數
   */
  onReachBottom: function () {
 
  },
 
  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {
 
  }
})

以上代碼能夠解決新版小程序受權登陸問題,可能有部分方法須要使用app.js和util.js,下面附上部分代碼:微信

app.js

//app.js
import util from './utils/util.js';
var loginStatus = true;
App({
  onLaunch: function () {
    //獲取微信頂部導航欄高度
    wx.getSystemInfo({
      success: res => {
        //導航高度
        this.globalData.navHeight = res.statusBarHeight + 46;
        console.log(res.statusBarHeight + 46)
      }, fail(err) {
        console.log(err);
      }
    })
    // 展現本地存儲能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
    //檢查登陸是否過時
    wx.checkSession({
      success: function (e) {   //登陸態未過時
        console.log("沒過時");
      },
      fail: function () {   //登陸態過時了
        console.log("過時了");
        //從新調取受權登陸接口
        util.checkLogin();
      }
    });
  },
  globalData: {
    userInfo: null,
    code:'',
    rootApi: 'https://www.toread.com.cn/index.php/sg/'
  }
})
util.js

var app = getApp();
 
// const rootApi = 'https://xxx/index.php/sg/';//測試環境
const rootApi = 'https://xxx/index.php/sg/';//線上環境
// 微信自定義格式化時間方法,傳入new Date()
const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
 
  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
/**
 * 時間格式化爲 時 分 秒(傳入時間爲毫秒)
 */
function MillisecondToDate(msd) {
  var time = parseFloat(msd) / 1000;
  if (null != time && "" != time) {
    if (time > 60 && time < 60 * 60) {
      time = parseInt(time / 60.0) + "分鐘" + parseInt((parseFloat(time / 60.0) -
        parseInt(time / 60.0)) * 60) + "秒";
    }
    else if (time >= 60 * 60 && time < 60 * 60 * 24) {
      time = parseInt(time / 3600.0) + "小時" + parseInt((parseFloat(time / 3600.0) -
        parseInt(time / 3600.0)) * 60) + "分鐘" +
        parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
          parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60) + "秒";
    }
    else {
      time = parseInt(time) + "秒";
    }
  }
  return time;
}
/**
 * 時間戳轉化爲年 月 日 時 分 秒
 * number: 傳入時間戳
 * format:返回格式,支持自定義,但參數必須與formateArr裏保持一致
*/
function zformatTime(number, format) {
 
  var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
  var returnArr = [];
 
  var date = new Date(number * 1000);
  returnArr.push(date.getFullYear());
  returnArr.push(formatNumber(date.getMonth() + 1));
  returnArr.push(formatNumber(date.getDate()));
 
  returnArr.push(formatNumber(date.getHours()));
  returnArr.push(formatNumber(date.getMinutes()));
  returnArr.push(formatNumber(date.getSeconds()));
 
  for (var i in returnArr) {
    format = format.replace(formateArr[i], returnArr[i]);
  }
  return format;
}
 
const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}
// post請求
function requestData(url, data0, successCallback, errorCallback) {
  wx.request({
    url: rootApi+url,
    data: data0,
    method: "POST",
    success: function (res) {
      successCallback(res);
    },
    error: function (res) {
      errorCallback(res);
    },
  });
}
 
// get請求
function getRequestData(url, data0, successCallback, errorCallback) {
  wx.request({
    url: rootApi+url,
    data: data0,
    method: "GET",
    success: function (res) {
      successCallback(res);
    },
    error: function (res) {
      errorCallback(res);
    },
  });
}
 
// 受權登陸
function login(data0, successCallback, errorCallback) {
  requestData('Login/check', data0, successCallback, errorCallback);
}
 
// 用戶登錄過時從新登陸
function checkLogin() {
  wx.login({
    success: res => {
      const code = res.code;
      // 獲取用戶信息
      wx.getSetting({
        success: res => {
          if (res.authSetting['scope.userInfo']) {
            // 已經受權,能夠直接調用 getUserInfo 獲取頭像暱稱,不會彈框
            wx.getUserInfo({
              success: res => {
                console.log(res);
                // 能夠將 res 發送給後臺解碼出 
                this.userInfo = res.userInfo;
                var iv = res.iv;
                var encryptedData = res.encryptedData;
                var postData = {};
                postData.code = code;
                postData.iv = res.iv;
                postData.encryptedData = res.encryptedData;
                //後臺服務器受權登陸接口
                this.login(postData,
                  (res) => {
                    console.log("login----")
                    if (res.data.code == 1) {//獲取成功 
                      console.log("檢測登錄過時後再次登陸成功!");
                      var utoken = res.data.utoken;
                      // 先移除可能須要更改的storage
                      // wx.removeStorageSync('utoken');
                      //設置本地緩存
                      wx.setStorage({
                        key: 'utoken',
                        data: utoken,
                      });
                      //用戶已經受權過
                      wx.reLaunch({
                        url: '/pages/index/index',
                      })
                    }
                    else {
                      wx.showModal({
                        title: '舒適提示',
                        content: res.data.msg
                      })
                    }
                  }
                )
                // 因爲 getUserInfo 是網絡請求,可能會在 Page.onLoad 以後才返回
                // 因此此處加入 callback 以防止這種狀況
                if (this.userInfoReadyCallback) {
                  this.userInfoReadyCallback(res)
                }
              }
            })
          }
        }
      })
    }
  })
}
 
// 去先後空格  
function trim(str) {
  return str.replace(/(^\s*)|(\s*$)/g, "");
}
 
// 提示錯誤信息  
function isError(msg, that) {
  that.setData({
    showTopTips: true,
    errorMsg: msg
  })
}
 
// 清空錯誤信息  
function clearError(that) {
  that.setData({
    showTopTips: false,
    errorMsg: ""
  })
}
//判斷字符串中是否含有表情符號
function isEmojiCharacter(substring) {
  for (var i = 0; i < substring.length; i++) {
    var hs = substring.charCodeAt(i);
    if (0xd800 <= hs && hs <= 0xdbff) {
      if (substring.length > 1) {
        var ls = substring.charCodeAt(i + 1);
        var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
        if (0x1d000 <= uc && uc <= 0x1f77f) {
          return true;
        }
      }
    } else if (substring.length > 1) {
      var ls = substring.charCodeAt(i + 1);
      if (ls == 0x20e3) {
        return true;
      }
    } else {
      if (0x2100 <= hs && hs <= 0x27ff) {
        return true;
      } else if (0x2B05 <= hs && hs <= 0x2b07) {
        return true;
      } else if (0x2934 <= hs && hs <= 0x2935) {
        return true;
      } else if (0x3297 <= hs && hs <= 0x3299) {
        return true;
      } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
        || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
        || hs == 0x2b50) {
        return true;
      }
    }
  }
}  
 
module.exports = {
  formatTime: formatTime,
  zformatTime: zformatTime,
  requestData: requestData,
  trim: trim,
  isError: isError,
  clearError: clearError,
  getRequestData: getRequestData,
  checkLogin: checkLogin,
  login:login,
  formatDuring:formatDuring,
  MillisecondToDate: MillisecondToDate,
  isEmojiCharacter: isEmojiCharacter
}
相關文章
相關標籤/搜索