微信小程序受权登陆、解密unionId出错

注:没有在微信开放平台作开发者资质认证的就不要浪费时间了,没认证没法获取unionId,认证费用300元/年,emmmm....php

微信受权登陆流程

第一步:wx.login获取 用户临时登陆凭证code前端

第二步:wx.getUserInfo获取加密过的数据encryptedData和解密参数ivnode

第三步:把步骤1、二中的code、encryptedData、iv传到开发者本身服务端python

第三步:服务端获取到code、encryptedData、iv以后用get方法请求以下微信接口c++

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code小程序

appid:小程序appid
secret: 小程序密钥
js_code: 第一步获取的临时登陆凭证code
grant_type:'authorization_code'
接口会返回 openid, session_key,注意:用户已经受权过的平台还会返回unionId,若是你只是须要unionId,则到此为止api

官方文档说法如图:
官方文档微信

没有受权过则用encryptedData、session_key、iv、appid、secret进行解密,官方多语言解密示例下载连接:
unionId解密示例
包含c++ php python nodesession

第四步:仿照示例解密后得到unionId,想作什么就作什么了~app

如下是受权登陆前端代码:

authLogin () {
    wx.login({
      success: loginRes => {
        let code = loginRes.code  // 获取用户临时code
        wx.getUserInfo({
          success: function (res) {
            let encryptedData = res.encryptedData  // 获取加密数据
            let iv = res.iv  //  解密参数
            // 发送解密必要数据到服务端
            wx.request({
              url: 'http://localhost',
              methods: 'POST',
              data: {
                code: code,
                encryptedData: encryptedData,
                iv: iv
              },
              succeess: res => {
                // 服务端首先调用微信接口获取session_key
                // 用户已经受权过的平台会直接返回unionId
                // 没有受权过则用session_key进行解密
                // 解密成功后服务端根据逻辑返回自定义信息
              }
            })
          }
        })
      }
    })
  }

以上步骤可行,可是微信调整了用户受权方式

接口调整

新的受权需用button组件调用getUserInfo,因此在这以前没法调用wx.login,可是若是先调用获取用户信息再调用wx.login的话,解密过程会出错,猜想code对应的session_key和以前getUserInfo获取的encryptedData不匹配

解决办法:
在页面的onLoad生命周期里调用wx.login,获取的code存入data以备须要的时候使用,可是code失效时间为5分钟,若是用户停留页面时间过长后点击受权登陆,此时的code已通过期了,因此,获取code的函数应该每4分钟左右调用一次

wxml按钮受权:
<button class="primary-bg" open-type='getUserInfo' bindgetuserinfo="authLogin">微信登陆</button>

js:

// 获取code
  onLoad: function (options) {
    this.getCodeTimer()
  },
  getCodeTimer () {
    wx.login({
      success: res => {
        this.data.code = res.code
        setTimeout(() => {
          this.getCodeTimer()
        }, 4 * 60 * 1000)
      }
    })
  },
  // 受权登陆
  authLogin(event) {
    if (event.detail.errMsg == 'getUserInfo:ok') {
      wx.showLoading()
      let reqData = {
        code: this.data.code,
        encryptedData: event.detail.encryptedData,
        iv: event.detail.iv
      }
      wx.request({
        url: 'http://localhost:8080',
        methods: 'POST',
        data: reqData,
        success: (res) => {
          console.log(res)
            // 请求完成
        }
      })
    } else {
      console.log('用户拒绝受权')
    }
  }

受权逻辑修改后实测没有出过错

相关文章
相关标签/搜索