最近發現小程序的登陸邏輯還有一些新的心得,因此記錄一下。
在小程序官網裏面會提到一個小程序的登陸邏輯,這是官方推薦的登陸邏輯,也就是所謂的小程序登陸態維護邏輯,這裏是官方的圖:html
官方邏輯的我的理解:redis
用戶打開微信小程序。數據庫
wx.login
獲取微信的 code,而後將這個 code 發送給開發者服務器(咱們本身的開發服務器)。開發者服務器接收到code 以後,會進行封裝處理,經過code2Session
這個api 接口來獲取真正須要的微信用戶的登陸態session_key
和 openid
和 unionid
。小程序
session_key
纔是真正的微信登陸態信息,可是把 openid
和 unionid
加起來一塊兒理解,也能夠籠統地理解爲這些都是微信的登陸態信息。而後須要開發者服務器本身生成一個自定義的登陸態(例如業務 token或者 session)來保存這些微信服務器返回來的微信登陸態相關信息(session_key
和 openid
和 unionid
),而且作關聯處理,而後返回給小程序客戶端。微信小程序
小程序客戶端接收到返回的自定義登陸態信息,從而判斷用戶是否登陸成功,登陸成功的話,就將自定義登陸態信息保存到本地的存儲。api
app.globaldata
,也能夠是 localstoage
,注意,小程序不支持 cookie
。開發者服務器的業務接口接收到請求,而且請求裏面攜帶了自定義的登陸態,經過校驗以後,會返回相關信息。promise
openid
或者 unionid
和 session_key
相匹配。code2Session
進行微信登陸態更新。整個微信小程序官方推薦的登陸態維護流程就是這樣了,官方推薦使用自定義登陸態來進行整個微信小程序的登陸維護,既然寄人籬下,那麼就要循序漸進,跟着政策走,這是最好的應對。
上面的圖裏面的一些術語解釋:緩存
code
是微信用戶的登陸憑證,打開小程序登陸的時候獲取的只屬於微信這個用戶的登陸憑證,須要注意的是,這個登陸憑證只供微信小程序使用的。code
的存活時間通常是5分鐘左右,這是一個臨時的登陸憑證,他的最大做用就是肯定是來源自哪個微信用戶來打開,是爲了後續生成一個微信登陸態 session_key
而使用的。session_key
是微信用戶在小程序裏面的登陸態信息,這是微信給這個用戶頒發的一個登陸 session
。服務器
{"session_key",openid":"..."}
,官方說須要按期使用wx.checkSession
檢測,可是在實際的場景裏面其實也能夠不用,用和不用主要看你怎麼設計你的微信小程序,這個後續會說。expire_time
過時時間的,可是後面取消了,這裏有一個比較新的官方回覆:用戶越頻繁使用小程序,session_key有效期越長,…… | 微信開放社區,有效期是3天,可是這個不必定是固定的,具體看業務需求,總的原則就是維護一個自定義登陸態,自定義登陸須要和微信登陸態關聯。 openId
,用戶在微信裏面的惟一標識,可是須要跟 unionid
進行一塊兒理解。unioinId
,若是開發者擁有多個移動應用、網站應用、和公衆賬號(包括小程序),可經過unionid
來區分用戶的惟一性,由於只要是同一個微信開放平臺賬號下的移動應用、網站應用和公衆賬號(包括小程序),用戶的unionid
是惟一的。換句話說,同一用戶,對同一個微信開放平臺下的不一樣應用,unionid
是相同的。微信
openId
就是微信用戶的惟一標識,可是由於微信產品不少,因此會出現多個微信產品使用不一樣的 openId
來標識用戶,可是對於咱們作業務接入的話,就買辦法使用了,因此建議是統一使用 unioinid
,由於通常來講,通常的業務都會有公衆號,小程序聯合使用的,因此 unionid
使用頻率較高。3rd_session
是通常是指開發者服務器的登陸態,也就是自定義登陸態,也就是咱們本身公司的業務服務器的登陸態(微信官方推薦使用自定義登陸態來管理整個微信小程序登陸)。
wx.checkSession
來檢查,若是過時了,就本地執行登陸操做,再讓開發者服務器跟微信服務器交互,獲取新的小程序登陸態,而後關聯到自定義登陸態。session_key
做爲表明理解。session
會話,官方說的3rd_session
就是這個。只有理解好官方的標準流程,才能更好地理解其餘流程,或者其餘人對官方流程的封裝和註解!
上面是基本的登陸流程理解,可是實際業務中仍是會有一些地方須要補充的,可是咱們理解的時候最好把他們分開,這樣會更清晰和簡單。
按照官方推薦的方式是使用自定義登陸態來管理整個微信小程序登陸流程的,雖說是經過一個自定義登陸態來管理,可是其實裏面是有變通的。
這裏有2種方式來作:
方式一:小程序打開的時候先檢查小程序本地是否有存儲的自定義登陸態,
若是有,則須要判斷這個自定義登陸態是否過時,這裏判斷的方式有2種,一種是開發者服務器提供一個接口來檢查,一種是在這個自定義登陸態數據裏面加上過時時間,判斷是否過時。
方式二:小程序打開的時候先發起wx.checkSession
檢查微信登陸態是否過時:
上面說的方式都是打開小程序的時候作的,可是也要考慮到一種狀況,就是自定義登陸態在用戶使用小程序的過程當中過時了,那麼這時候也是須要強制執行完整的登陸流程的。
相對來講方式二比較好,方式二的好處是不須要小程序服務端來參與校驗,而是在小程序端調用API。這種方式其實是將維護登陸態的機制委託給了微信維護的session_key,開發者不須要在自定義的登陸態中保存有效期信息。騰訊雲開發的wafer項目便採起了這種方法。
上面提到的方式二是在打開小程序的時候作的,這裏是在每次發起 HTTP 請求的時候作的,這個是不同的邏輯。
當小程序客戶端訪問接口的時候,開發者服務器返回說你的自定義登陸態過時了,你就須要從新發起完整的登陸,但這裏有2個點是須要注意的:
因此這裏就須要進行封裝一下,Random Notes這裏就提到了,思路是正確的,不過實現的話能夠按本身須要實現,他這裏有2個地方描述得很好,因此我搬過來借鑑了。
這是一個宏觀的,每一個請求都要檢查一下登陸態的邏輯圖:
圖片引用自:https://blog.imtouch.info
每一個請求都會檢查一次登陸態,不論是自定義登陸態仍是微信登陸態,反正只要發起跟開發者服務器交互的 HTTP 請求的以前都會檢查。
細分邏輯的話就會變成這樣:
圖片引用自:https://blog.imtouch.info
細分邏輯以後看起來會更加清晰,而且這裏的邏輯是微信登陸態和自定義登陸態都會檢查一遍,任何一個登陸態過時都會發起完整的登陸邏輯,其實我以爲這裏也能夠只判斷自定義登陸態的狀態也能夠的。
不過由此也帶來一個問題,就是若是一個頁面裏面有多個請求同時發起的話,那麼就會出現同時檢查到登陸態過時,而後同時發起登陸的狀況,這個問題可能會致使開發者服務器的校驗登陸數據出現問題,他這裏用到 promise.race
來解決,具體能夠看他的文章裏面介紹,我後面也會繼續寫一下這個處理的介紹。
參考文檔: