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

基础术语

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() 获取用户信息
  }
}
复制代码
相关文章
相关标签/搜索