最近在研究小程序,遇到想将一些账户信息和登录小程序的用户ID绑定到一起,但是官网简单例子里拿到的userInfo里面并没有用户唯一标识,因此就研究了下如何获取用户这个唯一标识的问题,而openid也足够我用了,在这里分享下获取方法:
官方文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject
OpenID和UnionID区别:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432
//app.js App({ onLaunch: function() { wx.login({ success: function(res) { if (res.code) { //发起网络请求 wx.request({ url: 'https://test.com/onLogin', data: { code: res.code } }) } else { console.log('获取用户登录态失败!' + res.errMsg) } } }); } })
可以看到代码中,第一个login方法是必须请求的,主要为了获取一个临时的code,用来请求其他用户的敏感数据,下面的wx.request中的url,官方是写的测试,正确应该是
https://api.weixin.qq.com/sns/jscode2session?appid=你的appId&secret=你的appSecret&js_code=刚才获取的CODE&grant_type=authorization_code
以上URL中appId和appSecret需要替换为自己的,后面的code就是前面你login返回的code,我们需要以此code来获取用户的openid。
需要注意的是,如果按照官方的文档,你是获取不成功的,调试的时候你会发现提示你api.weixin.qq.com这个域名不在你的request合法域名里,而且你也加不进去,因为说白了小程序还是前端代码,如果这样访问,就会把appId和appSecret这些敏感信息放在前端,这个是不允许的,因此,官方的建议是你将获取openid的操作封装到你的服务器,你通过将code请求到你自己的服务器,然后服务器来请求获取openid再返回结果给前端!!!
贴一下我的部分代码:
getUserOpenInfo: function (cb) { var that = this if (this.globalData.userOpenInfo) { typeof cb == "function" && cb(this.globalData.userOpenInfo) } else { //调用登录接口 wx.login({ success: function (res) { if (res.code) { wx.request({ url: 'https://我的获取openid的服务器地址', data: { code: res.code }, method: 'POST', header: { "content-type": "application/x-www-form-urlencoded" }, success: function (res) { if (res.data.code == 0) { that.globalData.userOpenInfo = res.data.data; typeof cb == "function" && cb(res.data.data); } else { typeof cb == "function" && cb(false) } }, fail: function () { typeof cb == "function" && cb(false) } }) } }, fail: function (res) { }, complete: function (res) { }, }) } }, globalData: { userInfo: null, userOpenInfo: null }
我的代码封装了返回的结果,正常微信官方返回的结果是以下的结构:
{ "openid" : "openid", "expires_in" : "过期时间,正常是7200,代表2小时", "session_key" : "session_key" }
这个是微信官方返回的,另外就是openId的过期问题,虽然官方返回了过期时间,但是就官方解释来看,openid是每个用户和每个公众号是唯一的,取值类似于hash(uuid,progromid)的概念,因此理论上是不存在过期的问题的。如果其他同学了解这个问题,也欢迎回复。