首先要明白一件事,小程序中的登陸和受權實際上是兩個操做。
登陸的意義就是讓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全局保存起來。