首先要明白一件事,小程序中的登陆和受权实际上是两个操做。
登陆的意义就是让web服务器知道当前的用户是谁,传统的web应用中用户经过输入帐号和密码实现登陆,而小程序中对应的是openId(当前用户对应的惟一标识)。javascript
每一个用户相对于每一个微信应用(公众号或者小程序)的openId 是惟一的,也就是说一个用户相对于不一样的微信应用会存在不一样的openId.
小程序中的受权分为不少种,使用摄像头、录音功能、用户信息等等,大多数状况下经过官方提供给的wx.authorize()
就能够获取对应的受权(弹出微信受权的对话框,用户容许以后便可得到),但今天要说的用户信息受权,在小程序一系列改版以后,则须要经过其余方式得到。html
下面是前端代码实现思路。前端
wx.login()
方法获取code(登陆凭证),而后发送给后台,后台就能够经过code2Session
向微信服务器请求到openid
和session_key
。mounted (){ wx.login({ success (res) { if (res.code){ // 这里能够把code传给后台,后台用此获取openid及session_key } }, }) }
wx.authorize()
就能够向用户发起某种受权请求,也就是弹窗询问用户是否赞成受权小程序使用某项功能或获取用户的某些数据。例如想调用设备的录音功能:vue
wx.authorize({ // 经过scope指明申请获取哪一种类型的权限 scope: 'scope.record', success() { // 用户已经赞成小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() } })
会弹出如下弹窗java
可是获取用户信息比较特殊,就像官方文档中说的:"wx.authorize({scope: "scope.userInfo"})
,不会弹出受权窗口,请使用 <button open-type="getUserInfo"/>
",也就是须要用户手动点击open-type=getUserInfo
的<button>
组件才能够弹出请求权限的弹窗。web
// template代码vuex
<button open-type="getUserInfo" @getuserinfo="bindGetUserInfo" @click="getUserInfoClick">获取权限</button>
//script代码小程序
getUserInfoClick(){ // console.log('click事件首先触发') }, bindGetUserInfo(e) { // console.log('回调事件后触发') const self = this; if (e.mp.detail.userInfo){ console.log('用户按了容许受权按钮') let { encryptedData,userInfo,iv } = e.mp.detail; self.$http.post(api,{ // 这里的code就是经过wx.login()获取的 code:self.code, encryptedData, iv, }).then(res => { console.log(`后台交互拿回数据:`,res); // 获取到后台重写的session数据,能够经过vuex作本地保存 }).catch(err => { console.log(`api请求出错:`,err); }) } else { //用户按了拒绝按钮 console.log('用户按了拒绝按钮'); } },
到这里就已经获取到用户的基本信息了,能够再稍微优化一下。虽然经过wx.getUserInfo()
方法已经不能弹出受权窗口,但受权状态会保存在缓存中,只要受权过且没过时,即可以经过此api的success回调直接获取到用户信息,不然进入会进入fail回调,此时咱们再提示用户点击<button>
组件进行主动过受权便可。api
// template代码缓存
<button v-i="buttonVisible" open-type="getUserInfo" @getuserinfo="bindGetUserInfo" @click="getUserInfoClick">获取权限</button>
// javascript代码
mounted () { const self = this; wx.login({ success (res) { if (res.code){ self.code = res.code; self.wxGetUserInfo(res.code); } }, }) }, methods: { wxGetUserInfo (code) { const self = this; wx.getUserInfo({ withCredentials: true, success (res) { let { encryptedData,userInfo,iv } = res; self.$http.post('api',{ code, encryptedData, iv, }).then(res => { console.log(`后台交互拿回数据:`,res); // 获取到后台重写的session数据,能够经过vuex作本地保存 }).catch(err => { console.log(`自动请求api失败 err:`,err); }) }, fail (err) { console.log('自动wx.getUserInfo失败:',err); // 显示主动受权的button self.buttonVisible = true; } }) }, bindGetUserInfo(e) { // console.log('回调事件后触发') const self = this; if (e.mp.detail.userInfo){ console.log('用户按了容许受权按钮') let { encryptedData,userInfo,iv } = e.mp.detail; self.$http.post(api,{ // 这里的code就是经过wx.login()获取的 code:self.code, encryptedData, iv, }).then(res => { console.log(`后台交互拿回数据:`,res); // 获取到后台重写的session数据,能够经过vuex作本地保存 }).catch(err => { console.log(`api请求出错:`,err); }) } else { //用户按了拒绝按钮 console.log('用户按了拒绝按钮'); } }, }
到这里,就经过mpvue简单实现了小程序得登陆及获取用户信息受权,总结一下:
wx.login()
获取code,也就是登陆凭证。open-type="userinfo"
的button组件,在回调事件中拿到encryptedData
以及iv
,与code一块儿传给后台,后台经过这些向微信服务器请求到openId和session_key以后,自定义登陆态并将其与openId 和session_key 关联起来而后写session。wx.setStorageSync()
方式讲session全局保存起来。