zoukankan      html  css  js  c++  java
  • 关于wx.getProfile和wx.login获取解密数据偶发失败的原因

    这是手机号正确获取的方式。

    wx.checkSession({
    success(){
    //session_key 未过期,并且在本生命周期一直有效
    //session_key还在啊
    Util.consolelog('session_key还在,在哪里?')
    that.getPhoneNumber(e);
    },
    fail(){
    // session_key 已经失效,需要重新执行登录流程
    wx.login({
    success(res) {
    if (res.code) {
    e.code=res.code;
    that.getPhoneNumber(e);
    } else {
    Util.consolelog('登录失败!' + res.errMsg)
    }
    }
    })
    }
    })

    再看看获取头像等的方式

    GetUserProfile: function (cb) {
    var that = this;
    console.log('this.globalData.GetUserProfile-that', that);
    console.log('this.globalData.GetUserProfile-this', that.userInfo);
    if (this.userInfo) {
    //typeof cb == "function" && cb(this.globalData.userInfo)
    typeof cb == "object" && cb.hasgetWxInfoSuccess(that.userInfo);
    } else {

    //调用登录接口
    wx.getUserProfile({
    desc: '业务需要',
    success(res){
    console.log('res',res);
    wx.login({
    success: function (r) {
    // console.log('login',r)
    typeof cb == "function" && cb(that.userInfo);


    try {
    var s = JSON.parse(res.rawData);
    } catch (e) {
    var s = {};
    }

    var o = {
    nick: s.nickName,
    sex: s.gender,
    avatar: s.avatarUrl,
    country: s.country,
    city: s.city,
    code: r.code,
    province: s.province,
    rawdata: res.rawData,
    encryptedData: res.encryptedData,
    signature: res.signature,
    iv: res.iv,
    rc_member_id: wx.getStorageSync('rc_member_id')
    };
    console.log('o', o);

    $.ajax({
    service: 'user.wxxcxLogin',
    method: 'POST',
    data: o,
    succ: function (res,all) {
    if (res && res.token) {
    $.setSession(res);
    if ($.store('RECM')) {
    var Partner = require("model/Partner.js");
    //有推荐会员ID+当前用户是登陆用户的话,发起关联关系2019年07月26日18:48:27
    Partner.RecMember.Add({
    data: {
    r_user_id: $.store('RECM'),
    channel: $.store('RECM_CHANNEL')?$.store('RECM_CHANNEL'):'link',
    channel_params: $.store('RECM_CHANNEL_PARAMS')?$.store('RECM_CHANNEL_PARAMS'):'unknow',
    },
    succ: function (res) {
    console.log('授权登陆时,推荐成功:', recm + '推荐了' + $.store('S[MEMBER]'))
    },
    fail: function (res,all) {
    console.log('授权登陆时,推荐失败:', all.msg);

    }
    })
    }

    cb.hasgetWxInfoSuccess(that.userInfo);

    }
    }
    });
    }
    });
    }
    });
    }
    },

    看到区别没有,获取头像的地方是每次都wx.login后传递了一个r.code,但是实际上如果把这个code带给后端用来解密会偶发解密失败。

    原因:

    你看这几个参数都是getProfile里获取的

    rawdata: res.rawData,
    encryptedData: res.encryptedData,
    signature: res.signature,

    只有code:r.code是wx.login里获取的

    你能确保res.encryptedData时用到的code和wx.login时的code一致吗?不一定的,官方有说明,特别是手机号获取的时候(说wx.login时会刷新登陆态,要checksession一下,这个同样适用于getProfile)。

    ===

    仔细读官方下面的这段话

    会话密钥 session_key 有效性

    开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。

    1. wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的 session_key。
    2. 微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。
    3. 开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。
    4. 当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。

    解决方案:

    <button @tap="GetUserProfile"></button>

    1、 

    getUserProfilePromise() {
    return new Promise((resolve, reject) => {
    uni.getUserProfile({
    desc: '获取您的昵称、头像、性别',
    success: userRes => {
    console.log('getUserProfile-res', userRes);
    resolve(userRes);
    },
    fail: userErr => {
    uni.showToast({
    title: '授权失败',
    icon: 'error'
    });
    console.log('getUserProfile-err', userErr);
    reject(userErr);
    }
    });
    });
    },
    getLoginCode() {
    return new Promise((resolve, reject) => {
    uni.login({
    provider: 'weixin',
    success: loginRes => {
    console.log('loginRes', loginRes);
    resolve(loginRes);
    }
    });
    });
    },


    GetUserProfile: function (cb) {
    var that = this;
    console.log('this.globalData.GetUserProfile-that', that);
    console.log('this.globalData.GetUserProfile-this', that.userInfo);
    if (this.userInfo) {
    //typeof cb == "function" && cb(this.globalData.userInfo)
    typeof cb == "object" && cb.hasgetWxInfoSuccess(that.userInfo);
    } else {
    //使用promise防止偶发解密失败问题2021-10-16 22:59:12
    // 注意使用函数的写法,避免出现错误
    let userProFile = this.getUserProfilePromise();
    let loginCode = this.getLoginCode();
    loginCode
    .then(code => {
    return code;
    })
    .then(codeFromWxLogin => {
    return new Promise((resolve, reject) => {
    userProFile
    .then(res => {
    resolve({ codeFromWxLogin, iv: res.iv, rawData: res.rawData, encryptedData: res.encryptedData, signature: res.signature,userInfoFromProfile:res.userInfo});
    })
    .catch(err => {
    reject(err);
    });
    });
    })
    .then(res => {
    console.log('promise-res', res);
    //执行网络请求
    typeof cb == "function" && cb(that.userInfo);

    /* try {
    var s =res;// JSON.parse(res.rawData);
    } catch (e) {
    var s = {};
    } */

    var o = {
    nick:res.userInfoFromProfile.nickName,
    sex:res.userInfoFromProfile.gender,
    avatar:res.userInfoFromProfile.avatarUrl,
    country:res.userInfoFromProfile.country,
    city:res.userInfoFromProfile.city,
    province:res.userInfoFromProfile.province,
    rawdata: res.rawData,
    encryptedData: res.encryptedData,
    signature: res.signature,
    iv: res.iv,
    code: res.codeFromWxLogin.code,
    rc_member_id: wx.getStorageSync('rc_member_id')
    };
    console.log('o', o);

    $.ajax({
    service: 'user.wxxcxLogin',
    method: 'POST',
    data: o,
    succ: function (res,all) {
    if (res && res.token) {
    $.setSession(res);
    if ($.store('RECM')) {
    var Partner = require("model/Partner.js");
    //有推荐会员ID+当前用户是登陆用户的话,发起关联关系2019年07月26日18:48:27
    Partner.RecMember.Add({
    data: {
    r_user_id: $.store('RECM'),
    channel: $.store('RECM_CHANNEL')?$.store('RECM_CHANNEL'):'link',
    channel_params: $.store('RECM_CHANNEL_PARAMS')?$.store('RECM_CHANNEL_PARAMS'):'unknow',
    },
    succ: function (res) {
    console.log('授权登陆时,推荐成功:', recm + '推荐了' + $.store('S[MEMBER]'))
    },
    fail: function (res,all) {
    console.log('授权登陆时,推荐失败:', all.msg);

    }
    })
    }

    cb.hasgetWxInfoSuccess(that.userInfo);

    }
    }
    });

    })
    .catch(err => {
    console.log('userProfile-err', err);
    });
    }
    },

  • 相关阅读:
    Apache虚拟主机配置(多个域名访问多个目录)(转)
    What I Learned as a Junior Developer Writing Tests for Legacy Code(转载)
    java.text包
    高性能前端框架React详解
    vue.js快速搭建图书管理平台
    vue.js用法和特性详解
    最接近原生APP体验的高性能前端框架——MUI
    用JS制作一个信息管理平台完整版
    JQuery实用技巧--学会你也是大神(1)——插件的制作技巧
    用JS制作一个信息管理平台(1)
  • 原文地址:https://www.cnblogs.com/showker/p/15415541.html
Copyright © 2011-2022 走看看