收藏
回答

手机号授权提示失败?

手机号授权提示失败,网上的大部分解决办法是,在回调里先`wx.checkSession`,如果还在登录态就不`wx.login`,以下是网上的解决代码

  getPhoneNumber (e) {
      //授权手机号,用户点击确认
    if ('getPhoneNumber:ok' === e.detail.errMsg) {
        wx.checkSession({
            success (res) {
                //session_key 未过期,并且在本生命周期一直有效
                const code = wx.getStorageSync('code')
                //将之前登录code传给后端,getPhoneNo是后端接口
        		getPhoneNo(code, e)
                   },
                fail () {
                  // session_key 已经失效,需要重新执行登录流程
                wx.login({
                    success: function(res) {
                    //将新获取的code传给后端,getPhoneNo是后端接口
                    getPhoneNo(res.code, e)
                    }
                })
            }
	})
    } else {
    ...
    }
  }


官方文档中给出

在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。

我对此的理解:

获取手机号授权,用户点击确定之后,有两种结果:

1. 在登录态:这种情况下,如果在回调中调用`wx.login`,此时可能刷新了登录态(code变成了新的code),但传给后端的加密信息,还是原来的sessionkey进行的加密信息(因为先获取的加密信息,在回调中调用的wx.login)。后端用新code去微信换取sessionKey,解老code对应的sessionkey加密的信息,导致解密失败。(个人理解,不知道对不对,有大神给孩子看一下吧~)

 正确的做法是,在登录态,不进行`wx.login`

2. 不在登录态,还是会存在 新code去微信换取sessionKey, 解老code对应的sessionkey加密的信息 这种情况啊?  哪理解错了?求指点!

最后一次编辑于  2021-07-28
回答关注问题邀请回答
收藏

2 个回答

  • 宋佳耀
    宋佳耀
    2021-07-28
    你这网上找的代码里看起来有处错误 wx.setStorageSync('code')
    

    应该是

    wx.getStorageSync('code')
    


    而且这代码确实也没解决新code解老数据的问题。。

    考虑一下登录时生成sessionkey存起来,随用随取。也可结合checkSession判断是否过期效果更佳

    2021-07-28
    有用
    回复 6
    • 好久不见
      好久不见
      2021-07-28
      谢谢,应该是wx.getStorageSync('code')我写错了。。。你说sessionkey存起来是后端存是吗?但是如果不在登录态,前端wx.login, sessionkey就改变了,是吧?我的问题就是不在登录态,wx.login获取新code去微信换取sessionKey, 解老code对应的sessionkey加密的信息,存在问题。
      2021-07-28
      回复
    • 宋佳耀
      宋佳耀
      2021-07-28回复好久不见
      过期了就重新登录 重新存一遍sessionKey,重新走一遍授权操作,用新sessionkey去解密新数据。
      2021-07-28
      回复
    • 好久不见
      好久不见
      发表于移动端
      2021-07-28回复宋佳耀
      所以即使不在登陆态,也不能直接wx.login是吧?
      2021-07-28
      回复
    • 宋佳耀
      宋佳耀
      2021-07-29回复好久不见
      wx.login现在是属于官方限制调用频率接口了。请求接口次数和打开应用次数的比值不能超过2,也就是一次运行小程序到退出,不能访问超过两次接口。
      一般的方案是把wx.login得到的相关数据缓存起来,避免多次请求。
      举个例子:
      在app.js里写个带回调方法参数的公用登录方法,以上来判断globaldata里有登录信息,则直接返回登录信息
      否则 走wx.login拿code,code去后端拿到sessionKey、openid 、unionid等数据保存到globaldata里并传递给参数中的callback方法
      在每个需登录功能子页onload中,上来就调用app.login方法获得登录信息后再执行其他操作,甚至都不需要去关心登录态,基本上在用户打开应用的周期内,不会丢失登录态,
      除非用户在某个页面长时间停留,这场景太少了。如果不放心的话可以在调用失败时检测登录态,如果失效重新调用一遍app.login(),这样用户在第一次操作失败后,再次操作就能
      正常执行了(因为第一次失败时自动登录了一次)。
      2021-07-29
      回复
    • 宋佳耀
      宋佳耀
      2021-07-29回复好久不见
      这个方案胜在比较简单,也能规避调用频率的问题。但是还有很多可提升的地方,比如为了安全可以改用token通信,避免openid和unionid直接暴露在外网数据包。比如用户体验上需要重复操作才能解决登录态过期问题。等等。
      2021-07-29
      回复
    查看更多(1)
  • 好久不见
    好久不见
    2021-07-28

    大佬们~

    2021-07-28
    有用
    回复
登录 后发表内容