背景
當我們要做一個擁有登錄功能的小程序時,面臨的第一個問題就是如何基于小程序建立用戶體系。
構建一個基于微信的用戶體系的核心思想是:獲取微信用戶的唯一身份標識,然后用唯一標識關聯或創建用戶體系。
唯一身份標識
微信生態內,一個微信用戶的唯一標識主要有兩個,OpenId和UnionId。
OpenId 是一個用戶對于一個小程序/公眾號的標識,開發者可以通過這個標識識別出用戶。
UnionId 是一個用戶對于同主體微信小程序/公眾號/APP的標識,開發者需要在微信開放平臺下綁定相同賬號的主體。開發者可通過UnionId,實現多個小程序、公眾號、甚至APP 之間的數據互通了。
在不變更主體的情況下,用戶的這兩個ID是永久不變的。即使,用戶刪掉了小程序,下次進來,仍可以使用這兩個ID進行辨識。
備注:變更主體,指的是將小程序綁定到其他開放平臺下。如果主體發生改變,那么該用戶的 unionid
將發生變化。
獲取唯一身份標識方式和流程
為了方便描述這個流程,我們直接看微信官方推薦的 login
最佳實踐。登錄流程時序圖如下所示:
獲取 OpenId
OpenId 是一個用戶對一個小程序/公眾號的標識,即使小程序更改了綁定主體,OpenId也不會變化。
獲取OpenId主要經過一下幾步:
- 小程序通過
wx.login()
獲取code
- 將
code
通過請求的方式,傳遞給后端 - 后端憑借
appid
、appsecret
、code
向微信接口服務發起請求,得到openid
和session_key
.
這樣就可以獲取用戶的OpenId。但是,實際情況,服務端僅僅拿到了OpenId還是不夠的。特別是,當小程序希望與其他小程序或者公眾號、APP進行互通或者聯動時(例如,使用小程序),我們需要使用 UnionId
,來作為應用與應用之間的橋梁。
因此,當存在多個應用需要互通的場景時,不可以使用 OpenId
作為唯一標識,因為 OpenId
僅針對單個應用而言。推薦使用 UnionId
作為用戶的唯一標識,在多個應用之間,它都是不變且唯一。
獲取UnionId
獲取 UnionId
的方式,可以歸為兩種:
- 靜默獲取UnionId(不一定可以獲取UnionId方式)。使用
code
方式,獲取UnionId
(只有特定場景,才能獲取到) - 解析加密數據獲取UnionId(一定可以獲取到UnionId方式)。小程序內通過
getUserInfo
,獲取到加密數據后,將code和加密數據傳遞給后端。后端通過code
,獲取session_key
,然后使用session_key
解密加密數據,獲取 UnionId。
方式一:靜默獲取UnionId
靜默獲取unionId方式,是在獲取 openId
的方式上,增加了返回UnionId的字段。具體流程見圖
靜默獲取UnionId的條件:
1.在微信開放平臺下存在同主體的App、公眾號、小程序。
2.用戶關注了某個相同主體公眾號,或曾經在某個相同主體App、公眾號上進行過微信登錄授權。
也就是說,如果用戶沒有關注過同主體的公眾號,也沒有在系統主題APP、公眾號進行微信登錄授權,那么就會獲取不到UnionId.
方式二:解析加密數據獲取UnionId
獲取步驟:
- 調用
wx.login
獲取code - 調用
wx.getUserInfo
獲取加密數據rawdata
- 服務端根據
code
,獲取session_key
,通過session_key
解密解密數據rawdata
,獲取UnionId
實踐中的登錄流程
方式一:
當已創建用戶,且可以通過code獲取UnionId,步驟如下:
- 調用
wx.login
獲取code - 服務端根據
code
,獲取OpenId
和UnionId
. - 若
UnionId
存在,根據UnionId
,查詢用戶是否存在,若存在,則返回登錄態;否則,報異常給小程序端 - 小程序根據異常,執行 「方式二」
方式二:
- 調用
wx.login
獲取code
- 調用
wx.getUserInfo
獲取加密數據rawdata
和userinfo
- 客戶端將
code
、rawdata
、userinfo
發送給服務端 - 服務端根據
code
,獲取session_key
和OpenId
、UnionId
. - 若
UnionId
存在,執行步驟 (7) - 若
UnionId
不存在,根據session_key
,服務端解密rawdata
,得到UnionId
. - 根據UnionId檢查用戶是否存在,若存在返回登錄態,否則,根據
UnionId
、OpenId
、Userinfo
創建用戶,并返回登錄態
雖然,服務端可以從 rawdata
解析得到 userinfo
,但是我們不一定會進行rawdata
的解析(根據code
,是否返回UnionId決定),因此,我們還是需要前端將userinfo
發送給后端。
為了更好的用戶體驗,對于曾經登錄過的用戶,避免出現授權彈窗,可以使用方式一進行登錄。這樣用戶就可以不用手動授權即可完成登錄。方式二,必須進行用戶授權才可以進行登錄。
未解決的問題
在開發過程,遇到了一些問題,暫時未能解決。例如,如何在小程序內喚起APP,讀取APP中的用戶信息,從而將APP的用戶與微信用戶進行綁定。
總結
本篇主要講述了在小程序內建立用戶體系的流程,以及獲取唯一身份標識的方式,和實踐中的登錄方式。本篇并不涉及代碼,具體代碼部分,我們將在下篇進行講解。