一个微信开放平台下的相同主体的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