评论

手机号解密失败完美解决方案

手机号解密失败解决方案

代码片段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是否已解析拿到,若拿到再进行手机号解密流程登录

如有问题,可在评论区互相讨论,一起学习成长~



点赞 0
收藏
评论
登录 后发表内容