手机号授权提示失败,网上的大部分解决办法是,在回调里先`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加密的信息 这种情况啊? 哪理解错了?求指点!
你这网上找的代码里看起来有处错误 wx.setStorageSync('code')
应该是
wx.getStorageSync('code')
而且这代码确实也没解决新code解老数据的问题。。
考虑一下登录时生成sessionkey存起来,随用随取。也可结合checkSession判断是否过期效果更佳
一般的方案是把wx.login得到的相关数据缓存起来,避免多次请求。
举个例子:
在app.js里写个带回调方法参数的公用登录方法,以上来判断globaldata里有登录信息,则直接返回登录信息
否则 走wx.login拿code,code去后端拿到sessionKey、openid 、unionid等数据保存到globaldata里并传递给参数中的callback方法
在每个需登录功能子页onload中,上来就调用app.login方法获得登录信息后再执行其他操作,甚至都不需要去关心登录态,基本上在用户打开应用的周期内,不会丢失登录态,
除非用户在某个页面长时间停留,这场景太少了。如果不放心的话可以在调用失败时检测登录态,如果失效重新调用一遍app.login(),这样用户在第一次操作失败后,再次操作就能
正常执行了(因为第一次失败时自动登录了一次)。
大佬们~