- 关于小程序获取手机号解密失败的踩坑历程
小程序中获取微信手机号的前提条件这里贴一个链接,各位同学自己看 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html 主要说说为什么会解密失败,主要有以下两点原因 微信服务器报错 你解密的姿势错了 对于第一点,比较少见,如果出现了,嗯 ,坐着等死就行了 解密失败一般是由于你的 sessionKey 失效导致的,而sessionKey 由 wx.login 这个api先获取code, 再由我们的后台拿这个code向微信服务器请求获得。code有效期五分钟。 上面的链接中有这样一句话 注意 在回调中调用 [代码]wx.login[代码] 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 [代码]login[代码];或者在回调中先使用 [代码]checkSession[代码] 进行登录态检查,避免 [代码]login[代码] 刷新登录态。 这句话这么理解呢,打个比方,假设你第一次调用wx.login获取的为 sessionKey_1,在它的有效期内,你再去获取一个加密数据 encryptedData_1,这时候你用sessionKey_1去解密encryptedData_1就可以正常解密。 但是在获取encryptedData_1的时候会有个回调函数,如果你在这个回调函数里又调了一次wx.login,获取了 sessionKey_2,这时候登录态可能会被刷新,加密encryptedData_1时使用的sessionKey_1就会失效,再去解密encryptedData_1就会有很高的几率解密失败。至于为什么不会百分百刷新登录态,鬼知道这逻辑是怎么写的。 贴上我的部分代码(只贴获取手机号的部分,其他逻辑请根据自己产品业务酌情参考) [代码][代码] const app = getApp(); [代码][代码] [代码]Page({[代码] [代码] [代码][代码]data: {[代码][代码] [代码][代码]code: [代码][代码]""[代码][代码],[代码][代码] [代码][代码]},[代码] [代码] [代码][代码]// 获取手机号[代码][代码] [代码][代码]getPhoneAndLogin: [代码][代码]function[代码][代码](e){[代码][代码] [代码][代码]let that = [代码][代码]this[代码][代码];[代码][代码] [代码][代码]// console.log(e);[代码] [代码] [代码][代码]if[代码] [代码](e.detail.errMsg !== [代码][代码]"getPhoneNumber:ok"[代码][代码]){[代码][代码] [代码][代码]return[代码][代码];[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]wx.showLoading({[代码][代码] [代码][代码]mask: [代码][代码]true[代码][代码],[代码][代码] [代码][代码]})[代码] [代码] [代码][代码]// 检查登录态是否过期[代码][代码] [代码][代码]wx.checkSession({[代码][代码] [代码][代码]success(res) {[代码][代码] [代码][代码]// session_key 未过期,并且在本生命周期一直有效[代码][代码] [代码][代码]// console.log(res);[代码] [代码] [代码][代码]wx.request({[代码][代码] [代码][代码]url: app.globalData.apiUrl + [代码][代码]'**********'[代码][代码],[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]code: that.data.code,[代码][代码] [代码][代码]encryptedData: e.detail.encryptedData,[代码][代码] [代码][代码]iv: e.detail.iv,[代码][代码] [代码][代码]},[代码][代码] [代码][代码]method: [代码][代码]"POST"[代码][代码],[代码][代码] [代码][代码]success: res => {[代码][代码] [代码][代码]// console.log(res);[代码] [代码] [代码][代码]},[代码][代码] [代码][代码]fail: res => {[代码][代码] [代码][代码] [代码][代码]wx.showToast({[代码][代码] [代码][代码]icon: [代码][代码]"none"[代码][代码],[代码][代码] [代码][代码]title: [代码][代码]'服务器繁忙'[代码][代码],[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码][代码] [代码][代码]complete: res => {[代码][代码] [代码][代码]wx.hideLoading();[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码][代码] [代码][代码]fail(err) {[代码][代码] [代码][代码]// session_key 已经失效,需要重新执行登录流程[代码] [代码] [代码][代码]wx.login({[代码][代码] [代码][代码]success: res => {[代码][代码] [代码][代码]that.data.code = res.code[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码][代码] [代码][代码] [代码][代码]/**[代码][代码] [代码][代码]* 生命周期函数--监听页面加载[代码][代码] [代码][代码]*/[代码][代码] [代码][代码]onLoad: [代码][代码]function[代码] [代码](options) {[代码][代码] [代码][代码]let that = [代码][代码]this[代码][代码];[代码][代码] [代码][代码]// console.log(options);[代码] [代码] [代码][代码]wx.login({[代码][代码] [代码][代码]success: res =>{[代码][代码] [代码][代码]that.data.code = res.code[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码] [代码]})[代码] 以上,如果有问题欢迎各位大佬指正
2018-11-28 - 「笔记」订阅消息-订阅次数维护
前言 距离1月10日模板消息下架只有2天了,在社区里经常能看到有帖子在问关于怎么记录订阅次数的问题,这里在这里介绍一下自己用的简单方案,仅供参考。 误区一 [图片] 上面这个图大家应该都比较熟悉了,很多人总是误以为勾选“总是保持以上选择,不再询问”,就可以无限发送订阅消息,这个是错误的想法,勾选和不勾选唯一的区别就是每次触发订阅的时候会不会弹授权窗口而已。 误区二 订阅消息不能通过bindsubmit的方式触发,必须通过bindtap的方式触发。 误区三 触发订阅窗口后,不管用户点击了允许还是取消,都会进入订阅消息的success回调中,所以通过这个来判断用户是否订阅是错误的。 订阅次数的维护 先看下官方的文档: [图片] 那么我们该如何使用呢? 我们通过 wx.requestSubscribeMessage 接口发送的时候是知道需要让用户订阅哪几个模板的,就是 tmplIds 这个参数填的数组。那么根据官方文档的回调内容,我们就可以直接在success内去获取对应的key所返回的状态。把获取到的状态分别存入自己的数据库里。发送的时候去数据库里查询需要发送的模板并且状态为accept的去发送,如果发送成功则删除一条记录(因为没有过期一说,所以随便删除哪一条记录都不影响)。 参考代码 [图片] 查询模板订阅状态 需要基础库大等于2.10.0才支持。 wx.getSetting({ withSubscriptions: true, success (res) { console.log(res) } }) 官方文档 补充 如果用户选择了不再接收消息会清空之前的订阅次数,但是这个不会主动告诉开发者,所以发送订阅消息失败后,需要根据返回内容自行清空记录,重新计算。 相关文章 「笔记」订阅消息-订阅次数维护(2020年3月更新改动) 「笔记」订阅消息体验踩坑
2020-03-06