代码片段:https://developers.weixin.qq.com/s/bRu1SfmD7UM5
常见的错误手机号快捷登录流程:
示例1:在app.js onLaunch中先调用wx.login解析sessionKey然后缓存在前端
示例2:进入登录页面后调用wx.login解析sessionKey然后缓存在前端
示例3:很多同学都是在点击按钮(open-type="getPhoneNumber")后再执行wx.login去解析sessionKey,但这样的话,
上方示例1、2中的sessionKey,如果小程序中未进行任何操作,等待一段时间后,该sessionKey有可能已过期,此时再执行手机号解密流程就会出现"手机号解密失败";
示例3中,执行getPhoneNumber后再执行wx.login去解析sessionKey,getPhoneNumber返回的encryptedData在微信后台中的sessionKey与当前wx.login解析的sessionKey不一致,此时再用该sessionKey去进行手机号解密时会出现"手机号解密失败"的现象
因此,手机号快捷登录解密手机号正确流程:
1. 先调用wx.login拿到加密code后,调用接口解析出sessionKey
2. 点击按钮(open-type="getPhoneNumber") 获取encryptedData、iv
3. 用sessionKey、encryptedData、iv、openId交给后端进行手机号解密再返回(获取直接用这些数据进行登录)
由此可知wx.login必须在getPhoneNumber之前调用,更新后台sessionKey(防止sessionKey过期),保证执行getPhoneNumber后面的操作的sessionKey一直是最新的
废话不多说,上代码:
1.登录页面login.wxml:
2.登录页面login.js:
const app = getApp();
Page({
data: {
isLoaded: false,
wxUserInfo:{},
},
onLoad() {
},
// 事件捕获,点击授权按钮前先wx.login更新sessionKey,防止失效
beforeClick() {
app.getUserOpenId({ isReload:true, success:(info) => {
console.log("info---", info);
let { wxUserInfo={} } = info;
this.setData({
isLoaded: true,
wxUserInfo
});
} });
},
async getPhoneNumber(e){
console.log("手机号授权登录---", e);
let { detail:{ code, encryptedData="", iv="" } } = e;
if(!encryptedData){
return;
}
this.setData({
"loginObj.loginType":"autoAuth"
});
this.timer = setInterval(() => {
let { isLoaded } = this.data;
console.log('setInterval---', this.isLoaded);
if (isLoaded) {
this.setData({ isLoaded: false });
clearInterval(this.timer);
let { wxUserInfo={} } = this.data;
let { sessionKey, openId } = wxUserInfo;
let params = {
encryptedData,
iv,
loginType:"autoAuth",
sessionKey,
openId
};
console.log("开始登录----");
// 到这里获取到的sessionKey跟微信后台的,就一直是一致的,不用担心解密失败
//...调用登录接口进行登录操作...
}
}, 100);
},
})
注意:app.getUserOpenId是封装起来挂载在app中的方法,凡是要用到wx.login这个api时,都可以用app.getUserOpenId来获取,防止sessionKey过期 ,也方便统一管理。(如果项目中有类似的公共方法,也建议这么做,非常方便管理哟)
代码如下:
/**
* 静默 获取openId、unionId、sessionKey
* isReload true-重新获取 false-取app.globalData中缓存的
* @returns
*/
async getUserOpenId(props){
let app = getApp();
let { wxUserInfo={} } = app.globalData;
// console.log("comm ---wxUserInfo", wxUserInfo);
let { success, isReload = false } = props || {};
if(!wxUserInfo.openId || isReload){
wx.login({
success(codeRes){
console.log("============>>>>>", codeRes);
let{ code } = codeRes;
let promise = getSessionKey(code);//这里的getSessionKey方法是调用wechat/jscode2session,需要后端同学配合,去找后端要即可
promise.then(res=>{
let{ data } = res;
if(data && data.success){
let { openid:openId, session_key:sessionKey, unionid:unionId } = data.result;
let wxUserInfo = { openId, sessionKey, unionId };
typeof success === "function" && success({ wxUserInfo });
app.globalData = Object.assign(app.globalData, { wxUserInfo });
}else{
}
})
return promise
}
})
}else{
typeof success === "function" && success({ wxUserInfo });
}
},
代码片段:https://developers.weixin.qq.com/s/bRu1SfmD7UM5
原理:利用 事件捕获 的特性,在点击按钮getPhoneNumber之前去执行wx.login后解析sessionKey,由于该操作是异步,因此在getPhoneNumber回调后需要setInterval循环判断sessionKey是否已解析拿到,若拿到再进行手机号解密流程登录
如有问题,可在评论区互相讨论,一起学习成长~
代码片段:https://developers.weixin.qq.com/s/bRu1SfmD7UM5
常见的错误手机号快捷登录流程:
示例1:在app.js onLaunch中先调用wx.login解析sessionKey然后缓存在前端
示例2:进入登录页面后调用wx.login解析sessionKey然后缓存在前端
示例3:很多同学都是在点击按钮(open-type="getPhoneNumber")后再执行wx.login去解析sessionKey,但这样的话,
上方示例1、2中的sessionKey,如果小程序中未进行任何操作,等待一段时间后,该sessionKey有可能已过期,此时再执行手机号解密流程就会出现"手机号解密失败";
示例3中,执行getPhoneNumber后再执行wx.login去解析sessionKey,getPhoneNumber返回的encryptedData在微信后台中的sessionKey与当前wx.login解析的sessionKey不一致,此时再用该sessionKey去进行手机号解密时会出现"手机号解密失败"的现象
因此,手机号快捷登录解密手机号正确流程:
1. 先调用wx.login拿到加密code后,调用接口解析出sessionKey
2. 点击按钮(open-type="getPhoneNumber") 获取encryptedData、iv
3. 用sessionKey、encryptedData、iv、openId交给后端进行手机号解密再返回(获取直接用这些数据进行登录)
由此可知wx.login必须在getPhoneNumber之前调用,更新后台sessionKey(防止sessionKey过期),保证执行getPhoneNumber后面的操作的sessionKey一直是最新的
废话不多说,上代码:
1.登录页面login.wxml:
2.登录页面login.js:
const app = getApp();
Page({
data: {
isLoaded: false,
wxUserInfo:{},
},
onLoad() {
},
// 事件捕获,点击授权按钮前先wx.login更新sessionKey,防止失效
beforeClick() {
app.getUserOpenId({ isReload:true, success:(info) => {
console.log("info---", info);
let { wxUserInfo={} } = info;
this.setData({
isLoaded: true,
wxUserInfo
});
} });
},
async getPhoneNumber(e){
console.log("手机号授权登录---", e);
let { detail:{ code, encryptedData="", iv="" } } = e;
if(!encryptedData){
return;
}
this.setData({
"loginObj.loginType":"autoAuth"
});
this.timer = setInterval(() => {
let { isLoaded } = this.data;
console.log('setInterval---', this.isLoaded);
if (isLoaded) {
this.setData({ isLoaded: false });
clearInterval(this.timer);
let { wxUserInfo={} } = this.data;
let { sessionKey, openId } = wxUserInfo;
let params = {
encryptedData,
iv,
loginType:"autoAuth",
sessionKey,
openId
};
console.log("开始登录----");
// 到这里获取到的sessionKey跟微信后台的,就一直是一致的,不用担心解密失败
//...调用登录接口进行登录操作...
}
}, 100);
},
})
注意:app.getUserOpenId是封装起来挂载在app中的方法,凡是要用到wx.login这个api时,都可以用app.getUserOpenId来获取,防止sessionKey过期 ,也方便统一管理。(如果项目中有类似的公共方法,也建议这么做,非常方便管理哟)
代码如下:
/**
* 静默 获取openId、unionId、sessionKey
* isReload true-重新获取 false-取app.globalData中缓存的
* @returns
*/
async getUserOpenId(props){
let app = getApp();
let { wxUserInfo={} } = app.globalData;
// console.log("comm ---wxUserInfo", wxUserInfo);
let { success, isReload = false } = props || {};
if(!wxUserInfo.openId || isReload){
wx.login({
success(codeRes){
console.log("============>>>>>", codeRes);
let{ code } = codeRes;
let promise = getSessionKey(code);//这里的getSessionKey方法是调用wechat/jscode2session,需要后端同学配合,去找后端要即可
promise.then(res=>{
let{ data } = res;
if(data && data.success){
let { openid:openId, session_key:sessionKey, unionid:unionId } = data.result;
let wxUserInfo = { openId, sessionKey, unionId };
typeof success === "function" && success({ wxUserInfo });
app.globalData = Object.assign(app.globalData, { wxUserInfo });
}else{
}
})
return promise
}
})
}else{
typeof success === "function" && success({ wxUserInfo });
}
},
代码片段:https://developers.weixin.qq.com/s/bRu1SfmD7UM5
原理:利用 事件捕获 的特性,在点击按钮getPhoneNumber之前去执行wx.login后解析sessionKey,由于该操作是异步,因此在getPhoneNumber回调后需要setInterval循环判断sessionKey是否已解析拿到,若拿到再进行手机号解密流程登录
如有问题,可在评论区互相讨论,一起学习成长~