微信小程序:wx.login和getPhonenumber获取手机号解密失败问题
Posted 彭世瑜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序:wx.login和getPhonenumber获取手机号解密失败问题相关的知识,希望对你有一定的参考价值。
原来的登录处理流程:
通过按钮点击触发,在处理函数内调用wx.login()
发现每次登录,第一次都会解密失败,第二次就成功了。
<button open-type="getPhoneNumber"
bindgetphonenumber="getPhonenumber">登录</button>
async getPhonenumber(e)
wx.login()
此时,是先点击的获取用户信息,再进行登录。
逻辑是不对的,因为获取手机号之后才进行的登录
第一次获取手机号,微信使用的是当前session_key
对手机号信息进行加密,而我们的session_key还是空的
,或者用户之前登录过,那么session_key就是上一次登录的状态
。解密失败。
第二次获取手机号,我们通过上次登录,获取了最新的session_key
,服务端也存了同样的一份session_key
, 微信加密和我们服务器解密使用的是同一份数据。解密成功。
解决办法
知道了登录的问题所在,当用户授权之前,应该使得服务端session_key
和 当前session_key
保持一致。
// 该方法应该在进入页面的时候,或者getPhonenumber之前调用
login()
// 如果有session_id,可以检查一下是否过期
wx.checkSession()
// 过期就登录
wx.login()
// 将session状态同步至服务器
// 登录成功后本地可以保存一份session_id
async getPhonenumber(e)
// 获取手机号逻辑
解决方法二:
微信基础库 2.21.2 开始 提供了新的获取手机号接口,通过动态令牌code就能换取用户手机号信息,能避免使用session_key不一致的问题。
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
微信小程序wx.login 和 wx.getUserProfile 同时使用问题
场景
在使用微信登录时,通常会在调用 wx.login
获取 code
后再通过 wx.getUserProfile
获取 iv
和 encryptedData
(加密数据)一起发到后端进行登录验证;
但是,在实际使用中如果在 wx.login
方法调用后再调用 wx.getUserProfile
会报错;
官方解释
也就是说,不能在调用方法的回调中使用 wx.getUserProfule()
;
解决方法
使用Promise.all()方法实现平级调用;
Promise.all()
方法接收一个promise
的iterable
类型(注:Array
,Map
,Set
都属于ES6 的iterable
类型)的输入,并且只返回一个Promise
实例, 那个输入的所有promise
的resolve
回调的结果是一个数组。这个Promise
的resolve
回调执行是在所有输入的promise
的resolve
回调都结束,或者输入的iterable
里没有promise
了的时候。它的reject
回调执行是,只要任何一个输入的promise
的reject
回调执行或者输入不合法的promise
就会立即抛出错误,并且reject
的是第一个抛出的错误信息。
简单点说就是会等到两个方法都回调成功该方法才会返回来值,返回值是一个数组。
代码
封装 wx.login
和 wx.getUserProfile
两个接口:
/**
* 使用promise封装用户信息接口
*/
getUserInfo:function(){
return new Promise((resolve,reject) => {
wx.getUserProfile({
desc: '用户登录', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
resolve(res)
},
fail:(err) => {
reject(err)
}
})
})
},
/**
* 使用promise封装wx.login接口
*/
getLogin:function(){
return new Promise((resolve,reject) => {
wx.login({
success (res) {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
},
封装登录接口
/**
* 登录接口
*/
login: function(){
let userRes = this.getUserInfo()
let loginRes = this.getLogin()
//使用promise.all()平级调用
Promise.all([userRes,loginRes]).then((res) => {
console.log(res)
let param = {
code: res[1].code,
iv: res[0].iv,
encryptedData: res[0].encryptedData
}
let data = {
method: "post",
url: api.apiName.wxLogin,
params: param
}
request.request(data).then(res => {
wx.setStorageSync('token', res.data)
wx.setStorageSync('hasLogin', true)
//获取用户信息
let data = {
method: "get",
url: api.apiName.getUserInfo,
params: null
}
request.request(data).then(res2 => {
wx.hideLoading({})
wx.setStorageSync('userInfo', res2.data)
}).catch(err => {
wx.hideLoading({})
console.log(err.msg)
})
setTimeout(function(){
wx.switchTab({
url: '../../index/index',
})
},1500)
}).catch(err => {
console.log(err.msg)
})
})
}
以上是关于微信小程序:wx.login和getPhonenumber获取手机号解密失败问题的主要内容,如果未能解决你的问题,请参考以下文章
微信小程序-bug-调用wx.login()无响应的原因和解决方案