小程序:授權、登錄、session_key、unionId
發表時(shí)間:2021-1-6
發布人(rén):融晨科技
浏覽次數:52
微信應用的(de)一個(gè)很大(dà)的(de)優勢就(jiù)在(zài)于(yú)使用過程中是(shì)不(bù)需要(yào / yāo)進行注冊和(hé / huò)顯式登錄的(de),大(dà)部分問題基本上(shàng)可以(yǐ)一鍵解決。但是(shì)在(zài)授權、登錄和(hé / huò)獲取用戶信息的(de)過程中都發生了(le/liǎo)哪些事情,今天我們就(jiù)來(lái)讨論一下。這(zhè)篇文章主要(yào / yāo)分析以(yǐ)下幾個(gè)問題:
- 授權和(hé / huò)登錄的(de)意義
- session_key 的(de)作用
- unionId 的(de)作用,有哪些獲取途徑
- 在(zài)應用中如何保存用戶登錄态
1. 授權和(hé / huò)登錄的(de)意義
首先必須要(yào / yāo)明白,授權和(hé / huò)登錄實際上(shàng)是(shì)兩個(gè)操作。
1.1 授權(已廢棄)
那授權的(de)作用是(shì)啥呢?從小程序官方文檔中我們可以(yǐ)看到(dào)授權操作隻需通過wx.authorize() 接口便可以(yǐ)完成,以(yǐ)下是(shì)文檔中對授權操作的(de)描述:
提前向用戶發起授權請求。調用後會立刻彈窗詢問用戶是(shì)否同意授權小程序使用某項功能或獲取用戶的(de)某些數據,但不(bù)會實際調用對應接口。如果用戶之(zhī)前已經同意授權,則不(bù)會出(chū)現彈窗,直接返回成功。
也(yě)就(jiù)是(shì)說(shuō),授權過程實際上(shàng)隻是(shì)在(zài)小程序前端獲得了(le/liǎo)操作部分wx 接口的(de)訪問許可,這(zhè)個(gè)過程實際上(shàng)是(shì)不(bù)會與開發者服務器發生任何關系的(de)。那這(zhè)些訪問許可包含哪些内容呢?再來(lái)看微信官方提供的(de)scope 列表:
1.2 登錄
所謂的(de)登錄就(jiù)是(shì)要(yào / yāo)讓開發者服務器知道(dào)當前的(de)用戶是(shì)誰?在(zài)傳統的(de)web 應用中,我們必須要(yào / yāo)讓用戶輸入賬号和(hé / huò)密碼才能實現登錄操作。但是(shì)在(zài)微信應用中,我們可以(yǐ)通過微信服務器來(lái)完成這(zhè)個(gè)操作,獲取到(dào)與當前用戶對應的(de)唯一标志(openId),具體操作實現流程如下:
注:每個(gè)用戶相對于(yú)每個(gè)微信應用(公衆号或者小程序)的(de)openId 是(shì)唯一的(de),也(yě)就(jiù)是(shì)說(shuō)一個(gè)用戶相對于(yú)不(bù)同的(de)微信應用會存在(zài)不(bù)同的(de)openId
從上(shàng)圖中,我們可以(yǐ)看出(chū),小程序中登錄步驟如下:
① 小程序前端使用wx.login() 從微信服務器獲取code
② 小程序前端将code 發送給開發者服務器,開發者服務器利用appId、appSecret 和(hé / huò)code 向微信服務器換換取用戶openId 和(hé / huò)session_key
③ 開發者服務器自定義登錄态并将其與openId 和(hé / huò)session_key 關聯起來(lái)然後寫session
④ 開發者服務器将登錄态返回給小程序前端,小程序前端使用wx.setStorageSync() 将登錄态保存起來(lái)
⑤ 小程序前端在(zài)執行業務請求時(shí)将登錄态發送給開發者服務器,以(yǐ)便開發者服務器知道(dào)當前操作的(de)用戶是(shì)哪位。
也(yě)就(jiù)是(shì)說(shuō),在(zài)整個(gè)過程中小程序前端是(shì)拿不(bù)到(dào)用戶openId 的(de),它隻能通過開發者服務器發給它的(de)登錄态來(lái)告訴服務器當前用戶的(de)信息。登錄過程中涉及session_key 和(hé / huò)unionId,于(yú)是(shì)又引出(chū)了(le/liǎo)下面的(de)問題。
2. session_key 的(de)作用
那麽,session_key 在(zài)登錄的(de)過程中或者登錄完成後起什麽作用呢?一起來(lái)看一下。
2.1 wx.getUserInfo
首先來(lái)看一下wx.getUserInfo 這(zhè)個(gè)api:
在(zài)設置withCredentials 屬性爲(wéi / wèi)true 的(de)情況下,這(zhè)個(gè)api 可以(yǐ)拿到(dào)encryptedData,iv 等敏感信息,encryptedData 需要(yào / yāo)使用session_key 進行解密,解密後可以(yǐ)拿到(dào)的(de)數據如下:
也(yě)就(jiù)是(shì)說(shuō),session_key 的(de)作用之(zhī)一是(shì)将小程序前端從微信服務器獲取到(dào)的(de)encryptedData 解密出(chū)來(lái),獲取到(dào)openId 和(hé / huò)unionId 等信息。但是(shì)在(zài)1.2 登錄過程中我們可以(yǐ)看到(dào)開發者服務器是(shì)能夠直接拿到(dào)用戶的(de)openId 信息的(de),而(ér)且unionId 也(yě)是(shì)有其他(tā)獲取途徑的(de),所以(yǐ)session_key 在(zài)這(zhè)裏的(de)作用看起來(lái)有點雞肋。
2.2 getPhoneNumber
session_key 更重要(yào / yāo)的(de)作用大(dà)概體現在(zài)獲取用戶手機方面(可能還包含其他(tā)敏感信息獲取api)。
從文檔中可以(yǐ)看到(dào)getPhoneNumber 返回的(de)用戶數據是(shì)加密過的(de),隻有使用session_key 才能解密,而(ér)小程序前端沒有session_key,所以(yǐ)無法獲取到(dào)用戶的(de)手機,隻能傳到(dào)開發者服務器進行處理。
3. unionId 的(de)作用,有哪些獲取途徑?
關于(yú)unionId 的(de)作用,可以(yǐ)參考Ref 中的(de)連接。簡單來(lái)說(shuō),就(jiù)是(shì)同一用戶針對同意微信公衆平台下綁定的(de)所有應用都具有相同的(de)unionId。
獲取途徑有三種,在(zài)官方文檔中寫的(de)比較清楚:
4. 在(zài)應用中如何保存用戶登錄态
保存用戶登錄态,一直以(yǐ)來(lái)都有兩種解決方案:前端保存和(hé / huò)後端保存。
4.1 後端保存
在(zài)1.2 步驟③ 中寫session 的(de)時(shí)候可以(yǐ)直接設定過期時(shí)間,定期通知小程序前端重新進行登錄(wx.login)。
4.2 前端保存
因爲(wéi / wèi)session_key 存在(zài)時(shí)效性問題(畢竟是(shì)用來(lái)查看敏感信息),而(ér)小程序前端可以(yǐ)通過wx.checkSession() 來(lái)檢查session_key 是(shì)否過期。所以(yǐ)可以(yǐ)通過這(zhè)個(gè)來(lái)作爲(wéi / wèi)保存用戶登錄态的(de)機制,這(zhè)也(yě)是(shì)小程序文檔中推薦的(de)方法: