首先要明白一件事,小程序中的登錄和授權其實是兩個操作。
登錄的意義就是讓web服務器知道當前的用戶是誰,傳統的web應用中用戶通過輸入賬號和密碼實現登錄,而小程序中對應的是openId(當前用戶對應的唯一標識)。
每個用戶相對於每個微信應用(公衆號或者小程序)的openId 是唯一的,也就是說一個用戶相對於不同的微信應用會存在不同的openId.
小程序中的授權分爲很多種,使用攝像頭、錄音功能、用戶信息等等,大多數情況下通過官方提供給的wx.authorize()
就可以獲取對應的授權(彈出微信授權的對話框,用戶允許之後即可獲得),但今天要說的用戶信息授權,在小程序一系列改版之後,則需要通過其他方式獲得。
下面是前端代碼實現思路。
- 調用
wx.login()
方法獲取code(登錄憑證),然後發送給後臺,後臺就可以通過code2Session
向微信服務器請求到openid
和session_key
。
mounted (){
wx.login({
success (res) {
if (res.code){
// 這裏可以把code傳給後臺,後臺用此獲取openid及session_key
}
},
})
}
- 只獲取到用戶的openid意義並不大,我們還需要用戶的暱稱、頭像等個人基本信息,獲取這些是需要用戶授權的。大多數情況下我們通過調用
wx.authorize()
就可以向用戶發起某種授權請求,也就是彈窗詢問用戶是否同意授權小程序使用某項功能或獲取用戶的某些數據。
例如想調用設備的錄音功能:
wx.authorize({
// 通過scope指明申請獲取哪種類型的權限
scope: 'scope.record',
success() {
// 用戶已經同意小程序使用錄音功能,後續調用 wx.startRecord 接口不會彈窗詢問
wx.startRecord()
}
})
會彈出以下彈窗
但是獲取用戶信息比較特殊,就像官方文檔中說的:"wx.authorize({scope: "scope.userInfo"})
,不會彈出授權窗口,請使用 <button open-type="getUserInfo"/>
",也就是需要用戶手動點擊open-type=getUserInfo
的<button>
組件纔可以彈出請求權限的彈窗。
// template代碼
<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>
組件進行主動過授權即可。
// 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,也就是登錄憑證。 - 拿到code之後,引導用戶觸發
open-type="userinfo"
的button組件,在回調事件中拿到encryptedData
以及iv
,與code一起傳給後臺,後臺通過這些向微信服務器請求到openId和session_key之後,自定義登錄態並將其與openId 和session_key 關聯起來然後寫session。 - 後臺將登錄態返回給前端,前端筒骨vuex或者
wx.setStorageSync()
方式講session全局保存起來。