引言
和小程序接触过的人应该都知道,同一个微信开放平台下的相同主体的App、公众号、小程序的unionid是相同的,这样就可以锁定是不是同一个用户。
UnionID机制
微信公众平台更新,为开发者提供UnionID机制。
经开发者反馈,由于同一公司下多个公众号之间需要用户帐号互通,微信开放平台提供了UnionID机制,来解决此问题。
通过获取用户基本信息接口,开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个公众号,可使用以下办法通过UnionID机制来在多公众号之间进行用户帐号互通。
将多个公众号绑定到同一个微信开放平台(open.weixin.qq.com)帐号下,即同一个Union下
通过获取用户基本信息接口中的UnionID来区分用户的唯一性,不过需要注意的是:公众号只有在被绑定到微信开放平台帐号下后,才会获取UnionID。只要是同一个微信开放平台帐号下的公众号,用户的UnionID是唯一的。换句话说, 同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。
一、注册微信开放平台
地址:http://open.weixin.qq.com/
二、绑定微信公众号
点击顶部 “管理中心”,选择进入“公众号”,再点击“绑定公众号”
只有通过微信认证的公众号才能绑定。
三、获取用户基本信息
这是使用高级接口中的获取用户基本信息来实现。
在第一个公众号下面获得的方倍的用户信息如下:
{
"subscribe": 1,
"openid": "oLVPpjqs9BhvzwPj5A-vTYAX3GLc",
"nickname": "方倍",
"sex": 1,
"language": "zh_CN",
"city": "广东",
"province": "深圳",
"country": "中国",
"headimgurl": "http://wx.qlogo.cn/mmopen/utpKYf69VAbCRDRlbUsPsdQN38DoibCkrU6SAMCSNx558eTaLVM8PyM6jlEGzOrH67hyZibIZPXu4BK1XNWzSXB3Cs4qpBBg18/0",
"subscribe_time": 1375706487,
"unionid": "oTBn-jt2RQSHdBoJQYFSdnZo8BBQ"
}
在第二个公众号下面获得的方倍的用户信息如下:
{
"subscribe": 1,
"openid": "ouBMEj6WFnUFBIUKe83VD7s7dft9",
"nickname": "方倍",
"sex": 1,
"language": "zh_CN",
"city": "广东",
"province": "深圳",
"country": "中国",
"headimgurl": "http://wx.qlogo.cn/mmopen/utpKYf69VAbCRDRlbUsPsdQN38DoibCkrU6SAMCSNx558eTaLVM8PyM6jlEGzOrH67hyZibIZPXu4BK1XNWzSXB3Cs4qpBBg18/0",
"subscribe_time": 1375726425,
"unionid": "oTBn-jt2RQSHdBoJQYFSdnZo8BBQ"
}
注意两个不同的用户信息
在不同的公众账号下openid是不一样的,而他们的unionid却是一样的。其他的信息不具有唯一性,没有比较意义。但基本信息是一致的。
这样就知道了关注两个公众账号的其实是同一个人。
四、UnionID的意义
对于拥有多个账号的企业来说,unionid可以帮助识别不同公众账号下的用户是否是同一个人。这样在不同账号下对该用户提供的服务可以联系起来了。
还可以去除重复关注的用户数,便于统计真实的关注用户总数。
解决方案的提出
微信针对不同的用户在不同的应用下都有唯一的一个openId。但是要想确定用户是不是同一个用户,就需要靠UnionId来区分。一般自己的后台都会有自己的一个用户表,每个用户有不同的userid。也就是说同一个用户在同一个微信开放平台下的相同主体的应用对应着相同的userid,unionid以及不同的openid。所以在用户登录进来的时候,我们只能靠微信返回给我们的unionid去判断是不是同一个用户,再去关联我们的用户表,拿到对应的userid。
接下来就是在获取unionid时的一些小问题分享一下:
首先,前端调用wx.login的时候会返回一个code,这个code传到后台的时候,就需要去调用微信的接口https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
传入 code,appid,secret去换取到openid,session_key以及unionid等信息。
这里就需要注意了。
官方文档上说的是
如果用户已经关注过公众号,或者曾经登录过App或公众号,则用户打开小程序时,开发者可以直接通过wx.login获取到该用户UnionID,无须用户再次授权。
就是因为没有注意到这句话,所以后来改了好多东西,这里分为两种情况,
(1)用code换取的时候,返回了unionid,这样就皆大欢喜了,你可以根据unionid以及openid去判断该用户有没有用户信息,从而获取userid或者生成userid返回给前端
(2)悲剧的情况,unionid返回为null,这时候你没法儿关联出用户的userid。后来再去看官方文档的时候,发现有针对这种情况的方法。就是需要前端再去调wx.getUserInfo()这个接口。这时候微信会返回很多数据(详情见微信官方文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/open.html),这些数据里面有一个encryptedData,这个数据中就包含你需要的unionid以及其他的很多用户信息啦。获取到以后将encryptedData、加密算法的初始向量iv返回给后端,后端根据这两个数据以及之前的session_key就可以解密出你需要的数据了。