微信小程式登入-openid和unionid
阿新 • • 發佈:2018-11-02
本文轉自https://www.cnblogs.com/yaoyuqian/p/8203792.html
我們一般都是先獲取到微信的 unionid,然後再通過 unionid 去登入自己的網站,就可以關聯到使用者在自己網站上的 user_id,但是在小程式登入中,有時候可以獲取到 unionid,有時候獲取不到,在獲取不到 unionid 的情況下,使用者無法正常登入網站。 UnionID機制說明: 如果開發者擁有多個移動應用、網站應用、和公眾帳號(包括小程式),可通過 unionid 來區分使用者的唯一性,因為只要是同一個微信開放平臺帳號下的移動應用、網站應用和公眾帳號(包括小程式),使用者的 unionid 是唯一的。換句話說,同一使用者,對同一個微信開放平臺下的不同應用,unionid 是相同的。 同一個微信開放平臺下的相同主體的 App、公眾號、小程式,如果使用者已經關注公眾號,或者曾經登入過App或公眾號,則使用者開啟小程式時,開發者可以直接通過二般情況下(即在登入小程式之前,既沒有關注過公眾號,也沒有登入過公眾號,更沒有使用微信登入的方式登入過app),通過 wx.login 的到的 code 換不回 unionid 及 openid 等資訊。 解決思路:通過帶登入態的 wx.getUserInfo 獲取到使用者的加密資料 encryptedData 和加密演算法的初始向量iv,然後將 encryptdata、iv 以及 code傳給後端,後端再去通過接收到的encryptedData、iv以、code 以及之前的 session_key 解密出使用者的 openid、unionid 等。1. 獲取code(登入憑證,用來換取openid及session_key等) wx.login({ success: function(res){ if(res.code){ that.getNeededUserInfo(res.code); }else{ console.log('獲取使用者登入態失敗!'+res.errMsg); } } }) 2. 獲取使用者資訊(利用wx.login返回的code獲取使用者的資訊) getNeededUserInfo: function(code){ wx.request({ url: 'https://my.com/login', method: 'POST', data: { code: code // 後端通過這個code去呼叫微信的介面(https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),傳入引數code、appid、appsecret後獲取到微信返回的unionid、openid及session_key等。(然後後端可以直接利用微信返回的資訊去關聯使用者在自己網站的user_id) }, success: function(res){ // 可以返回前端需要的使用者資訊(包括unionid、openid、user_id等) } }) }
1. 獲取code(登入憑證,用來換取openid及session_key等)
wx.login({
success: function(res){
if(res.code){
that.getNeededUserInfo(res.code);
}else{
console.log('獲取使用者登入態失敗!'+res.errMsg);
}
}
})
2. 獲取加密資料和加密演算法初始向量
舊版本基礎庫調取wx.getUserInfo()可以直接獲取到微信返回的encryptdata等完整資料,基礎庫更新之後,需要增加withCredentials屬性,並將屬性值設定為true時才可以獲取到除使用者基本資訊之外的encryptedData以及iv等資料。
需要注意的是:當withCredentials值為true時,要求此前有呼叫過wx.login且登入態尚未過期。
getEncData: function(){
wx.getUserInfo({
withCredentials: true,
success: function(res){
that.getNeededUserInfo( code, res.encryptedData, res.encryptedData );
}
})
}
3. 獲取使用者資訊(利用wx.login返回的code獲取使用者的資訊)
getNeededUserInfo: function(code, enc, iv){
wx.request({
url: 'https://my.com/login',
method: 'POST',
data: {
code: code,
encryptedData: enc,
iv: iv
},
success: function(res){
// 可以返回前端需要的使用者資訊(包括unionid、openid、user_id等)
}
})
}
實際專案中需要將以上兩種情況整合以後使用。
思路有兩種:
第一種:( 前端判斷是否有 unionid )在向後端上傳 code 並且後端返回資料以後,前端判斷返回值中是否有 unionid 或者 unionid 是否為 null,null 的情況下去呼叫帶有使用者登入態的wx.getUserInfo(),然後再將微信返回的 encryptedData 和 iv 返回給後端,後端解密出相應的資訊後再返回給前端;
第二種:( 後端判斷是否有 unionid )前端在呼叫 wx.getUserInfo() 時候帶著登入態,然後不管後臺能不能拿到 unionid,都把 encryptedData 和 iv 返回給後端,後端在拿到前端 code 之後去請求微信的介面拿 unionid,如果返回的 unionid 為空,再拿前端傳的 encryptedData、iv以及之前的 session_key 解密出 unionid。