unionId
一個微信開放平台下的相同主體的App、公眾號、小程序的unionid是相同的,這樣就可以鎖定是不是同一個用戶
微信針對不同的用戶在不同的應用下都有唯一的一個openId, 但是要想確定用戶是不是同一個用戶,就需要靠unionid來區分
同一個微信開放平台下的相同主體的 App、公眾號、小程序,如果用戶已經關注公眾號,或者曾經登錄過App或公眾號,則用戶打開小程序時,開發者可以直接通過 wx.login 獲取到該用戶UnionID,無須用戶再次授權
(解讀:用戶如果沒有登錄過app,也沒有登錄過公眾號,也沒有關注過公眾號的情況下,小程序中通過 wx.login 是獲取不到 unionid的)
UnionId 機制文檔:https://developers.weixin.qq.com/miniprogram/dev/api/unionID.html
UnionID獲取途徑
-
綁定了開發者帳號的小程序,可以通過下面3種途徑獲取UnionID。
-
調用接口wx.getUserInfo,從解密數據中獲取UnionID。注意本接口需要用戶授權,請開發者妥善處理用戶拒絕授權后的情況。
-
如果開發者帳號下存在同主體的公眾號,並且該用戶已經關注了該公眾號。開發者可以直接通過wx.login獲取到該用戶UnionID,無須用戶再次授權。
-
如果開發者帳號下存在同主體的公眾號或移動應用,並且該用戶已經授權登錄過該公眾號或移動應用。開發者也可以直接通過wx.login獲取到該用戶UnionID,無須用戶再次授權
用到的API
- wx.login(obj)
- wx.getUserInfo(obj)
注意:getUserInfo此接口有調整,使用該接口將不再出現授權彈窗,請使用<button open-type="getUserInfo"></button>
坑:
我們一般都是先獲取到微信的 unionid,然后再通過 unionid 去登錄自己的網站,就可以關聯到用戶在自己網站上的 user_id,但是在小程序登錄中,有時候可以獲取到 unionid,有時候獲取不到,在獲取不到 unionid 的情況下,用戶無法正常登錄網站。
原因:同一個微信開放平台下的相同主體的 App、公眾號、小程序,如果用戶已經關注公眾號,或者曾經登錄過App或公眾號,則用戶打開小程序時,開發者可以直接通過 wx.login 獲取到該用戶UnionID,無須用戶再次授權
(解讀:用戶如果沒有登錄過app,也沒有登錄過公眾號,也沒有關注過公眾號的情況下,小程序中通過 wx.login 是獲取不到 unionid的)
所有就有兩種情況:
-
一般情況,用戶登錄過關聯的其他公眾號
使用 wx.login 獲取code,傳到后端,code換openid,unionId
//1.login wx.login({ success: function(data) { wx.request({ url: openIdUrl, data: { code: data.code }, success: function(res) { self.globalData.openid = res.data.openid }, fail: function(res) { console.log('拉取用戶openid失敗,將無法正常使用開放接口等服務', res) } }) }, fail: function(err) { console.log('wx.login 接口調用失敗,將無法正常使用開放接口等服務', err) callback(err) } })
-
用戶沒有用過關聯的公眾號等
這時候 wx.login 就獲取不到 unionId 了。需要使用 wx.getUserInfo
解決思路:通過帶登錄態的 wx.getUserInfo 獲取到用戶的加密數據 encryptedData 和加密算法的初始向量iv,然后將 encryptdata、iv 以及 code傳給后端,后端再去通過接收到的encryptedData、iv以、code 以及之前的 session_key 解密出用戶的 openid、unionid 等
wx.getUserInfo({ withCredentials:false, success:(obj)=>{ wx.request({ url: openIdUrl, data: { code: data.code, encryptedData : obj.encryptedData, iv : obj.iv, }, success: function(res) { self.globalData.openid = res.data.openid }, fail: function(res) { console.log('拉取用戶openid失敗,將無法正常使用開放接口等服務', res) } }) } })
實際項目中,需要將兩種情況整合使用
兩種方案:
第一種:( 前端判斷是否有 unionid )wx.login 向后端上傳 code 並且后端返回數據以后,前端判斷返回值中是否有 unionid 或者 unionid 是否為 null,null 的情況下去調用帶有用戶登錄態的wx.getUserInfo(),然后再將微信返回的 encryptedData 和 iv 返回給后端,后端解密出相應的信息后再返回給前端;
第二種:( 后端判斷是否有 unionid )前端調用 wx.login(), wx.getUserInfo() ,把 code,encryptedData 和 iv 返回給后端,后端在拿到前端 code 之后去請求微信的接口拿 unionid,如果返回的 unionid 為空,再用的 encryptedData、iv以及之前的 session_key 解密出 unionid,后端解密出相應的信息后再返回給前端
鏈接:https://www.jianshu.com/p/46efa68d9033