微信小程序打夯之旅(一):登陸流程

基礎術語

1. code: 調用wx.login後返回的臨時登陸憑證,可請求微信服務器換取openId和session_key
2. openId:用戶惟一標識,同一用戶在不一樣的應用中不一致
3. session_key:對用戶數據進行加密簽名的密鑰
4. appId:小程序惟一標識,申請小程序成功後得到分配
5. unionId:用戶在開放平臺的惟一標識符,同一用戶在同一帳號下的全部應用中一致
複製代碼

UnionID 機制說明

若是開發者擁有多個移動應用、網站應用、和公衆賬號(包括小程序),可經過unionid來區分用戶的惟一性,由於只要是同一個微信開放平臺賬號下的移動應用、網站應用和公衆賬號(包括小程序),用戶的unionid是惟一的。換句話說,同一用戶,對同一個微信開放平臺下的不一樣應用,unionid是相同的。javascript

UnionID獲取途徑

UnionID 獲取途徑:綁定了開發者賬號的小程序,能夠經過下面的途徑獲取 UnionIDcss

  • 調用接口 wx.getUserInfo,從解密數據中獲取 UnionID。注意本接口須要用戶受權,請開發者妥善處理用戶拒絕受權後的狀況。html

  • 若是開發者賬號下存在同主體的公衆號,而且該用戶已經關注了該公衆號。開發者能夠直接經過 wx.login + code2Session 獲取到該用戶 UnionID,無須用戶再次受權。java

  • 若是開發者賬號下存在同主體的公衆號或移動應用,而且該用戶已經受權登陸過該公衆號或移動應用。開發者也能夠直接經過wx.login + code2Session 獲取到該用戶 UnionID,無須用戶再次受權。算法

  • 用戶在小程序(暫不支持小遊戲)中支付完成後,開發者能夠直接經過 getPaidUnionId 接口獲取該用戶的 UnionID,無需用戶受權。注意:本接口僅在用戶支付完成後的5分鐘內有效,請開發者妥善處理。小程序

  • 小程序端調用雲函數時,若是開發者賬號下存在同主體的公衆號,而且該用戶已經關注了該公衆號,可在雲函數中經過 cloud.getWXContext 獲取 UnionID後端

  • 小程序端調用雲函數時,若是開發者賬號下存在同主體的公衆號或移動應用,而且該用戶已經受權登陸過該公衆號或移動應用,也可在雲函數中經過 cloud.getWXContext 獲取 UnionIDapi

小程序登陸流程示意圖

1. 經過wx.login() 獲取code
2. 將code發送給後端,後端請求微信服務器code2Session接口換取openId和sessionKey
3. 將openId與惟一登陸態綁定並把登陸態返回給用戶
複製代碼

image

須要受權的信息

部分接口須要通過用戶受權贊成才能調用,如用戶信息、地理位置、地址等等,須要注意的是,若是用戶已經拒絕了受權,就不會再出現受權彈窗,此時應該引導用戶前往設置界面打開受權,開發者能夠調用 wx.openSetting 打開設置界面,引導用戶開啓受權。bash

提早發起受權服務器

除了 userInfo,其餘的受權信息均可以使用 wx.authorize 提早發起受權,而 userInfo 只能經過 button 觸發。

// 點擊後將出發彈窗,點擊容許或拒絕將調用回調
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">

getUserInfo(e) {
  // 用戶拒絕受權
  if (e.detail.errMsg == 'getUserInfo:fail auth deny'){
    this.showError('您尚未受權微信登陸');
  } else {
    // 獲取用戶信息成功
    this.weixinLoginNew();
  }
}
複製代碼

e.detail 數據結構說明(跳過吧)

  • encryptedData: 加密後的用戶敏感信息,如openId和unionId
  • iv:加密算法的初始向量,後端經過iv、encryptedData及解密算法進行解密得到openId
  • signature:數據簽名,signature = sha1( rawData + session_key ),開發者將 signature、rawData 發送到開發者服務器進行校驗。服務器利用用戶對應的 session_key 使用相同的算法計算出簽名 signature2 ,比對 signature 與 signature2 便可校驗數據的完整性。
  • userInfo:用戶非敏感信息,包含頭像、暱稱、性別等

須要受權的信息列表

scope 對應接口 描述
scope.userInfo wx.getUserInfo 用戶信息
scope.userLocation wx.getLocation, wx.chooseLocation 地理位置
scope.address wx.chooseAddress 通信地址
scope.invoiceTitle wx.chooseInvoiceTitle 發票擡頭
scope.invoice wx.chooseInvoice 獲取發票
scope.werun wx.getWeRunData 微信運動步數
scope.record wx.startRecord 錄音功能
scope.writePhotosAlbum wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum 保存到相冊
scope.camera <camera />組件 攝像頭

獲取手機號

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>

Page({
  getPhoneNumber(e) {
    // 揭祕後JSON結構:{phoneNumber(有區號), purePhoneNumber, countryCode }
    console.log(e.detail.encryptedData)
  }
})

複製代碼

案例(封裝了一個微信登陸組件)

1. 查看用戶設置信息驗證是否受權過

ready() {
  wx.getSetting({
    success: (res) => {
      if (res.authSetting['scope.userInfo']) {
        // 已經受權,能夠直接調用 wx.getUserInfo 獲取頭像暱稱
        this.setData({ isAuthorization : true});
      }
    }
  });
}
複製代碼

2. 頁面結構 若是已經受權過,則能夠直接調用 wx.getUserInfo 無需按鈕受權,slot 中能夠放置任何元素,用以描述登陸按鈕。

<view class="login-wrap" catchtap="weixinLogin">
  <slot></slot>
  <button wx:if="{{ !isAuthorization }}" open-type="getUserInfo" bindgetuserinfo="getUserInfo" class="wx-btn" size="min">
  </button>
</view>
複製代碼
// 數據
data: {
  isAuthorization: false,     // 是否已經驗證過
  canIUse: wx.canIUse('button.open-type.getUserInfo'),
},
複製代碼
/* 樣式 */
<style lang="scss">
.login-wrap {
  position: relative;
}
.wx-btn {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0rpx;
  top: 0rpx;
  z-index: 100;
  border-radius:0rpx;
  background:none;
  margin:0rpx;
  padding:0rpx;
}

.wx-btn:after {
  border: none;
}
</style>
複製代碼

3.處理點擊行爲 若是用戶已經受權,則會觸發 weixinLogin 事件。

weixinLogin (e) {
  if (!this.data.isAuthorization) return;
  // 經過 wx.login() 完成微信登陸
  // 經過 wx.getUserInfo() 獲取用戶信息
},
複製代碼

若是用戶未受權過,則會觸發 getUserInfo 事件。

// 微信登陸按鈕觸發getUserInfo
getUserInfo(e) {
  if (!this.data.canIUse){
    this.showError('請升級微信到最新版本');
    return;
  }
  if (e.detail.errMsg == 'getUserInfo:fail auth deny'){
    this.showError('您尚未受權微信登陸');
  } else{
    wx.showLoading({ title: 'loading', mask: true });
    // 經過 wx.login() 完成微信登陸
    // 經過 wx.getUserInfo() 獲取用戶信息
  }
}
複製代碼
相關文章
相關標籤/搜索