评论

已解决。小程序获取手机号时,checkSession通过但是获取手机号解密失败

小程序获取手机号偶尔解密失败

  • 一开始我的处理方式是在页面直接用checkSession,我的session_key是在index.js登录的时候保存到storage,这里check回调的是“success”。
  • 但是把此时storage里面的session_key结合授权按钮的参数去进行解密是失败的,需要在当前的Page再登陆一次才能成功。
  • 不推荐把session_key存放在缓存。所以以上做法直接跳过。
  • 最后参考了一个朋友的做法,在Page onLoad的时候执行一次wx.login(),然后拿到新的session_key,再用此时的新key去解密就通了。或者改为请求解密之前执行一次登录,据说出问题的概率还是很大
  • 结尾补充:最后一种方法还有个问题要考虑,就是最好执行获取手机号之前再checkSession一下(尽管没啥用)。

问题源头,由于这个函数在校验session_key的时候,无论是过期的key还是新的key都是success,所以有了之后一些列的问题,session_key的状态没法把控

Page({
  data: {
  	currentSessionKey: null
  },
   
  onLoad: function(options) {
    /* do something*/
  	const here = this;
    // 执行登录确保session_key在线
    wx.login({
      success(res) {
        if (res.code) {
        // call()是我自己基于wx.request封装的一个请求函数工具,这里通过后端发送登录请求获得openid
          const data = call(userLogin, {
            code: res.code
          });
          data.then(obj => {
            if (!obj.error) {
              here.setData({ currentSessionKey: obj.result.session_key })
            }
          });
        }
      },
      fail(error) {
        throw error;
      }
    });
  },
   
  // 点击按钮获取手机号权限并解析<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" bindtap='doMyAction'>获取手机号</button>
  getPhoneNumber: function (e) {
  	const { encryptedData, iv } = e.detail;
    const options = { encryptedData: encryptedData, iv: iv, sessionKey: this.data.currentSessionKey };
    here.doGetPhone(options);
  },
   
  doMyAction: function() {
    // 还可以做一些事情
  },
 
  doGetPhone: function (options) {
    const {
      sessionKey,
      encryptedData,
      iv
    } = options;
 
    const here = this;
    // 向服务器请求解密
    wx.request({
     // 这里是解密用的接口
      url: 'https://xxx.com/python/decrypt',
      method: 'POST',
      data: {
        sessionKey: sessionKey,
        encryptedData: encryptedData,
        iv: iv
      },
      success(res) {
        // 最终获取到用户数据,国家代号前缀、不带前缀的手机号。默认是不带前缀
        const { countryCode, purePhoneNumber } = res.data;
        here.pageForward(countryCode, purePhoneNumber);
      },
      fail(error) {
        console.log(error);
        here.pageForward();
      }
    })
  },
   
  pageForward: function(countryCode, purePhoneNumber) {
   // 获取成功后我是跳转到另一个页面
    wx.navigateTo({
      url: `/pages/person/index?phone=${purePhoneNumber}`
    })
  }
})
最后一次编辑于  2020-09-15  
点赞 5
收藏
评论

31 个评论

  • crow
    crow
    2022-03-19

    我现在是把获取到的session_key维护在redis里面,key的过期时间目前是设置的30分钟,经常会出现解密失败的问题,近期出现特别多,目前反馈登陆失败信息的都是湖南的用户,前端这边尝试过登陆失败自动再重试一次,问题同样存在,我现在不确定跟session_key的过期时间有没有关系

    2022-03-19
    赞同
    回复
  • 彭世瑜
    彭世瑜
    2022-01-20

    请问解决了吗?

    先wx.login,将code传服务器,返回后接着获取手机号,第一次解密失败,第二次成功,这个过程必现

    2022-01-20
    赞同
    回复
  • 王妙端
    王妙端
    2021-10-14

    直接通过云函数获取

    新建云函数:

    云函数:login

    index.js:

    const cloud = require('wx-server-sdk')
    cloud.init()
    exports.main = async (event) => { return { ...event, ...cloud.getWXContext() } }
    


    <button open-type="getPhoneNumberbindgetphonenumber="getPhoneNumber">获取tel</button>

    getPhoneNumber: function (e) {

        wx.cloud.callFunction({

          name: 'login',

          data: {weRunData: wx.cloud.CloudID(e.detail.cloudID)}

        }).then(res => {

          console.log('云函数')

          console.log(res)

          console.log('电话号码'+res.result.event.weRunData.data.phoneNumber)

        })

      }


    2021-10-14
    赞同
    回复
  • 王明
    王明
    2021-06-09

    为啥不见微信 官方的解决方案哪

    2021-06-09
    赞同
    回复
  • 你的阿陈哥
    你的阿陈哥
    2021-05-26

    我也遇到的了同样的问题,在授权获取手机号并发给后端解密的时候总是解密失败!!!

    但我的代码流程是没有问题的。

    我先wx.checkSession查看用户session_key是否过期,过期则执行wx.login重新登录刷新session。但是某个用户在checkSession时我得到的总是seccess,然后数据发给后端却解密失败!!(然而我认为用户登录态实际已经过期了,但checkSession总是给我错误的指引!

    后来我改进,在后端返回解密失败后我再执行一次wx.login登录并刷新session_key后并给用户抛出提示:请在此点击重试!。用户再次点击授权后就解密成功了!!!

    ps:难道微信官方对这个惊天大bug没有一点发现?? 真是让人头痛啊

    2021-05-26
    赞同
    回复
  • 含光
    含光
    2021-04-15

    话说我在解密手机号的前一个步骤获取sessionKey再传给后端解密能不能一步到位,这样sessionkey是不是就是唯一的值了呢?不再使用checkSession这个函数了,因为他无论成功还是失败都是success,我觉得这个思路应该是正解。有疑问请说出理由

    2021-04-15
    赞同
    回复 3
    • Oliver
      Oliver
      2021-04-30
      不确定用户是否会在页面停留过久,如果停留较长一段时间,sessionKey又过期了
      2021-04-30
      回复
    • 王明
      王明
      2021-06-30
      你解决,没我感觉也是这个问题
      2021-06-30
      回复
    • 含光
      含光
      2021-07-09回复王明
      还是会解密失败,需要解密两次,无论放到前端还是后端解密都会这样
      2021-07-09
      回复
  • 小坏จุ๊บ
    小坏จุ๊บ
    2020-09-15

    手机号解密失败?扫盲帖+解决方案? - 微信开放社区 https://developers.weixin.qq.com/community/develop/article/doc/000208a8ba43c0d15afa4117c5b813

    希望对大家有帮助

    2020-09-15
    赞同
    回复
  • 2020-08-11

    感觉很不科学

    2020-08-11
    赞同
    回复
  • Oliver
    Oliver
    2020-06-06

    还有一种做法可能更稳定些,就是在点击获取手机号的时候去login一下,就是倒数第二条那里的代码搬到点击事件

    2020-06-06
    赞同
    回复 1
    • Oliver
      Oliver
      2020-07-31
      看了下面的回复,这个做法确实失败几率挺高,不可取
      2020-07-31
      回复
  • 陈亮
    陈亮
    2020-06-05

    官方有解决了吗

    2020-06-05
    赞同
    回复

正在加载...

登录 后发表内容