關於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);
});
}
},


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM