收藏
回答

绑定手机号,偶发第一次失败第二次成功?

用户登录后,去绑定手机号时,偶尔出现,第一次绑定失败,再点击绑定一次成功,怎么解决,wx.login到底应该放哪呢?有说放onLoad, 1.onLoad每次都wx.login好吗?2.登录后再checkSession都是true的 3.官方api说wx.login前置获取,前置到哪呢

求官方回复

回答关注问题邀请回答
收藏

1 个回答

  • 杭州弧途科技有限公司
    杭州弧途科技有限公司
    03-24
    官方文档地址:
    
    https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
    
    获取手机号能力是我们小程序自该能力开放出来后就立即投入去开发的,主要是业务与用户账号强关联,大家都用过封装了该能力的组件,但是应该还没去了解如何实现的。
    
    如何使用:
    
    wxml:
    <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
    js:
    getPhoneNumber(e) {
    console.log(e.detail.errMsg) //最初这里判断超复杂,各种不等于判断,安卓、IOS不一致,开发者工具调试与真机不一致,且场景比较多(拒绝、允许、关闭、发送短信、未绑定等)最后跟官方的提出:判断成功可以给个统一的errMsg或者code。直到后来'getPhoneNumber:ok'出来,该问题才解决。
      console.log(e.detail.iv)
      console.log(e.detail.encryptedData)
    }
    错误写法:
    getPhoneNumber(e){
    wx.login({
    success: (res) => {
    let postData = {
    url: 'xxx',
    data: {
    code: res.code,
    iv: e.detail.iv,
    encryptedData: e.detail.encryptedData
    }
    }
    }
    })
    }
    getWechatCode(callback) {
      wx.login({
        success: (res) => {
          wx.setStorage({
            key: 'miniCode',
            data: res.code,
            complete: () => {
              callback && callback()
            }
          })
        }
      })
    },
    正确写法为:
    onLoad() {
    getApp().getWechatCode()
    },
    getPhoneNumber(e) {
    let postData = {
     url: 'xxx',
     data: {
     code: wx.getStorageSync('code'),
     iv: e.detail.iv,
     encryptedData: e.detail.encryptedData
     }
    }
    }
    ​
    js:
    attached() {
    //---------登录有效期检查
    wx.checkSession({
      success: ()=> {
        //session_key 未过期,并且在本生命周期一直有效
      },
      fail: ()=> {
        // session_key 已经失效,需要重新执行登录流程
        wx.login() //重新登录
      }
    })
    },
    getPhoneNumber(e) {
    let postData = {
     url: 'xxx',
     data: { //如果session_key有效不传code,只给iv和encryptedData找后端解密(后端发现无sesion_key就使用iv + encryptedData 解密)
     iv: e.detail.iv,
     encryptedData: e.detail.encryptedData
     }
    }
    }
    老代码:
    let postData = {
      url: 'xxx',
      data: {
        path: 'xxx', //小程序路径
        scene: `xxx` //码内参数
      }
    }
    <image src="https://xxx?scene=id=xxx&page=xxx" />
    
    分享下小程序码频繁获取失败的问题原因: access_token失效。刚开始做小程序码的时候,生产和测试环境共用同一个access_token, 导致生产使用access_token,测试就失效,测试使用,生产失效。这块的缓存策略最初由 晴天哥 -> 二祥哥 -> 少天。解决方案点这里 。
    
    我们拿到该链接通过wx.getImageInfo或者wx.downLoadfile等方法,拿到菊花码本地链接,生成分享图。
    
    后端不上传七牛,前端直接通过get请求调用接口,返回文件流。
    
    解决:
    
    提交参数给后端后,生成的码后端会先上传七牛,期间可能存在超时的情况导致值上传失败,返回前端的路径打开是空白的。
    
    问题:
    
    老规矩,不会说话,就贴代码:
    
    根据我们现在的情况,肯定是采用接口B了。
    
    区别的话,以前我写到简书了地址
    
    接口A,正方形的小程序码(不限次数)
    
    接口B,菊花码(不限次数)
    
    接口C,菊花码(10w次)
    
    如果获取小程序二维码?官方提供了三个接口:
    
    --------------------------------------获取小程序二维码----------------------------------------
    
    我们获取到code后发送给后端换取session_key,需要授权的地方我们可通过提前调用 wx.checkSession 接口检测当前用户登录态是否有效,有效就正常拿session_key找后端换取手机号,如果无效那么我们可以再调用 wx.login 获取新的用户登录态。
    
    接下来操作了:
    
    session_key为临时登录调用凭证,该字段有效期不限,随时失效,用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效,具体时效逻辑微信未透露。
    
    code有效期5分钟,session_key不透露有效期,根据用户活跃来,活跃时间越长有效期越长。
    
    为啥要这样做呢?
    
    通过session_key当code去换取用户手机号。
    
    所以当时讨论了还有另外一种方案:
    
    目前的操作方法,虽然未出现什么大问题,但是频繁获取code,频繁刷新登录态,可能会导致一些不可预期的情况出现。
    
    后续优化方案:
    
    这样操作后,获取手机成功率目前是100%,暂未出现解密失败的情况,目前封装到 open-button组件内了,大家可自行查看文件。
    
    在需要授权的页面,生命周期为 onLoad或者组件内的created 里调用(重要,一定要提前调用,否则会出现解密失败):
    
    获取code 统一封装到app.js里,并存到缓存中:
    
    这里表现错误形式为:后端经常性的解密失败,60%成功,40%失败,失败率挺高。后翻继续翻阅文档,以及在上线前一天临时改了个解决方案,就是目前的方案,一直用到现在(后面有更优解决方案):
    
    当然这里踩了一个坑:     wx.login在getPhoneNumber之后去获取code。
    
    js里的操作拿到的只是用户手机号的加密信息,这里可以通过后端调用官方提供的解密算法即可。
    
    03-24
    赞同
    回复
登录 后发表内容
问题标签