1. 程式人生 > 其它 >一文詳解小程式授權、登入、session_key和unionId

一文詳解小程式授權、登入、session_key和unionId

微信應用的一個很大的優勢就在於使用過程中是不需要進行註冊和顯式登入的,大部分問題基本上可以一鍵解決。但是在授權、登入和獲取使用者資訊的過程中都發生了哪些事情,今天我們就來討論一下。這篇文章主要分析以下幾個問題:

  • 授權和登入的意義
  • session_key 的作用
  • unionId 的作用,有哪些獲取途徑
  • 在應用中如何儲存使用者登入態

 

一、授權和登入的意義

首先必須要明白,授權和登入實際上是兩個操作。

 

1.1 授權

那授權的作用是啥呢?從小程式官方文件中我們可以看到授權操作只需通過wx.authorize() 介面便可以完成,以下是文件中對授權操作的描述:

提前向用戶發起授權請求呼叫後會立刻彈窗詢問使用者是否同意授權小程式使用某項功能或獲取使用者的某些資料

,但不會實際呼叫對應介面【比如說在呼叫獲取使用者資訊介面前,需要使用者授權,但在授權過程中並不呼叫 獲取使用者資訊介面】。如果使用者之前已經同意授權,則不會出現彈窗,直接返回成功。

也就是說,授權過程實際上只是在小程式前端獲得了操作部分wx 介面的訪問許可,這個過程實際上是不會與開發者伺服器發生任何關係的。那這些訪問許可包含哪些內容呢?再來看微信官方提供的scope 列表:

注:新版api已廢棄wx.authorize()

 

1.2 登入

所謂的登入就是要讓開發者伺服器知道當前的使用者是誰?在傳統的web 應用中,我們必須要讓使用者輸入賬號和密碼才能實現登入操作。但是在微信應用中,我們可以通過微信伺服器來完成這個操作,獲取到與當前使用者對應的唯一標誌(openId)

,具體操作實現流程如下:

wx.login()用來做登入的方法,呼叫介面獲取登入憑證,code傳送給後端用於置換session_key和openid等資料。每個使用者相對於每個微信應用(公眾號或者小程式)的openId 是唯一的,也就是說一個使用者相對於不同的微信應用會存在不同的openId。

 

 

這是小程式官方的一張登入流程圖,現在就來解讀一下這個流程

  • 前端wx.login()獲取code,呼叫後端介面,將得到的code傳送到後端
  • 後端呼叫微信介面,用appid+appsecret+code傳送過去,置換到session_key+openid,以前是不能置換unionid的,但是現在在滿足以下條件可以置換到unionid 
    • 微信開放平臺下存在同主體的App、公眾號、小程式
    • 使用者關注了某個相同主體公眾號,或曾經在某個相同主體App、公眾號上進行過微信登入授權 同時滿足以上兩個條件就能拿到使用者unionid,這樣一來,就能在wx.login()準確識別出使用者是誰
  • 自定登入態與openid和session_key關聯,實際就是生成一個與openid,session_key關聯的token,下發給前端。
  • 前端將後端下發的token存入快取,在後面的介面請求中帶上自定登入態

 

以上就是小程式的整個登入流程,可以看到其實並不是一定要wx.getUserInfo()才能拿到使用者的資訊,在特定的條件下,通過wx.login()的呼叫拿到unionId也能後端資料庫裡拿到使用者資訊。登入過程中涉及session_key和unionId,於是又引出了下面的問題。

 

二、session_key 的作用

那麼,session_key在登入的過程中或者登入完成後起什麼作用呢?一起來看一下。

2.1 wx.getUserInfo

首先來看一下wx.getUserInfo 這個api:

 

在設定withCredentials 屬性為true 的情況下,這個api 可以拿到encryptedData,iv 等敏感資訊,encryptedData 需要使用session_key 進行解密,解密後可以拿到的資料如下:

 也就是說,session_key的作用之一是將小程式前端從微信伺服器獲取到的encryptedData 解密出來,獲取到openId 和unionId等資訊

但是在1.2登入過程中可以看到開發者伺服器是能夠直接拿到使用者的openId資訊,而且unionId 也是有其他獲取途徑,所以session_key 在這裡的作用看起來有點雞肋。

 

2.2 getPhoneNumber

session_key 更重要的作用大概體現在獲取使用者手機方面(可能還包含其他敏感資訊獲取api)。

從文件中可以看到getPhoneNumber 返回的使用者資料是加密過的,只有使用session_key才能解密,而小程式前端沒有session_key,所以無法獲取到使用者的手機,只能傳到開發者伺服器進行處理。

 

三、unionId 的作用,有哪些獲取途徑?

 

3.1、UnionID機制說明

如果同一公司擁有多個移動應用、網站應用、和公眾帳號(包括小程式),可通過unionid來區分使用者的唯一性,因為只要是同一個微信開放平臺帳號下的移動應用、網站應用和公眾帳號(包括小程式),使用者的unionid是唯一的。換句話說,同一使用者,對同一個微信開放平臺下的不同應用,unionid是相同的。

Tip:unionid 用於識別同一主體下不同賬號之間的使用者。舉例說明:就是公司有A訂閱號,B服務號,同一個人關注A和B,會得到不同的OPENID,但是會得到相同的unionid。這樣就可以識別到相同的使用者,用於不同賬號之間打通使用者關係。

 

3.2、UnionID獲取途徑

必須有一個微信開放平臺賬號綁定了至少一個微信公眾賬號或者網站應用或者小程式,否則UnionID返回null。綁定了開發者帳號的小程式,可以通過下面3種途徑獲取UnionID。

方法一:呼叫介面wx.getUserInfo,從解密資料中獲取UnionID。注意本介面需要使用者授權,請開發者妥善處理使用者拒絕授權後的情況。

方法二:如果開發者帳號下存在同主體的公眾號,並且該使用者已經關注了該公眾號。開發者可以直接通過wx.login獲取到該使用者UnionID,無須使用者再次授權。

方法三:如果開發者帳號下存在同主體的公眾號或移動應用,並且該使用者已經授權登入過該公眾號或移動應用。開發者也可以直接通過wx.login獲取到該使用者UnionID,無須使用者再次授權。


 

四、在應用中如何儲存使用者登入態

儲存使用者登入態,一直以來都有兩種解決方案:前端儲存和後端儲存。

4.1 後端儲存

在1.2 步驟③ 中寫session 的時候可以直接設定過期時間,定期通知小程式前端重新進行登入(wx.login)。

4.2 前端儲存

因為session_key 存在時效性問題(畢竟是用來檢視敏感資訊),而小程式前端可以通過wx.checkSession() 來檢查session_key 是否過期。所以可以通過這個來作為儲存使用者登入態的機制,這也是小程式文件中推薦的方法:

 文章源地址:https://cloud.tencent.com/developer/article/1766827