一個微信開放平臺下的相同主體的App、公衆號、小程序的unionid是相同的,這樣就能夠鎖定是否是同一個用戶html
微信針對不一樣的用戶在不一樣的應用下都有惟一的一個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。api
調用接口wx.getUserInfo,從解密數據中獲取UnionID。注意本接口須要用戶受權,請開發者妥善處理用戶拒絕受權後的狀況。微信
若是開發者賬號下存在同主體的公衆號,而且該用戶已經關注了該公衆號。開發者能夠直接經過wx.login獲取到該用戶UnionID,無須用戶再次受權。session
若是開發者賬號下存在同主體的公衆號或移動應用,而且該用戶已經受權登陸過該公衆號或移動應用。開發者也能夠直接經過wx.login獲取到該用戶UnionID,無須用戶再次受權app
注意: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