已解决。小程序获取手机号时,checkSession通过但是获取手机号解密失败? 葫芦娃救爷爷 Raven R 的评论 - 微信开放社区 https://developers.weixin.qq.com/community/develop/article/doc/000ee852ac0d281f6809d6b2a56813?jumpto=comment&commentid=0000aa2efec9b01fc67b7eee9564
目前看就是 encryptedData, iv 解密的时候失效,而这两个是在点击按钮后获得的,如果在按钮的 handler 里面检查session_key失效,又重新去wx.login了,这时候获得的 encryptedData, iv 对应的session_key 和 当前的session_key 是不统一的。于是解出来也是白板。虽然有时候这样做,还是可以运行通过的,那是因为在较短的时间内 连续获取的 session_key,似乎会是一样的。至少我测试下来是这样。这个较短的时间是多长?可能是一根烟的功夫。这种连续获取session_key情形是不是只在开发者工具中发生?不知道,也不重要,于是不用费劲去猜,跟没必要再深入试。
那么如果 把检查 并且重新登录的逻辑 放在 页面的 onload 上行不行呢?
行,但假如说用户长时间没有操作,那么还是要在 使用 session_key 之前 再检查一次。如果失效了,那么得引导一次重新wx.login。
这部分逻辑 根本不可能是 if else 那么简单,实践中要复杂很多。要注意的是 已经获取到 encryptedData, iv 之后,发现 session_key 失效了,那就算重新login 也还是得重新获取 一次 encryptedData, iv。无法避免的 需要用户界面操作一次。
我采用了比较简单的粗暴办法来应对这种情况。
session_key 和用户的id等基本信息 组合成dict然后加密成 token,然后存入小程序客户端。发动服务端请求的时候 把token 发还,服务端解密后 取session_key出来用。
自己封装一个 login的 promise 函数,在函数中如果token有效 那么就直接返回,无效,那么就重新登录。login 得是一个 promise函数,并且要暂存这个 promise,用来防止多次执行的登录,这样也会变换session_key。如果执行了,在那么直接返回暂存的 promise就行了。
在page的 onload 事件上 绑定一个 装饰器,在装饰器内 使用封装好的函数,检查checkSession() 如果可用,那么就正常login,如果失效那么就强制登录(即使token有效也把它换掉)
最后 app Lanuch 的时候 把 用户的 token 清掉。
《来自开发者的答复,没有理解》
开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。微信通过用户加密信息进行解密获取用户数据,偶发性得出现解密失败,解密成功次数比较多,是什么原因?? peng 的回答 - 微信开放社区 https://developers.weixin.qq.com/community/develop/doc/000024a0cd0f30d01c3a23a9458c00?jumpto=comment&commentid=000ea6ccb18b58361e3a821f15ac
- wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的 session_key。
- 微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。
- 开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。
- 当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。