小程序開發-梳理登陸流程-v1.0

最近發現小程序的登陸邏輯還有一些新的心得,因此記錄一下。

1、官方微信小程序登陸流程我的理解

在小程序官網裏面會提到一個小程序的登陸邏輯,這是官方推薦的登陸邏輯,也就是所謂的小程序登陸態維護邏輯,這裏是官方的圖:html

官方邏輯的我的理解:redis

  1. 用戶打開微信小程序。數據庫

    • 也能夠是在須要的時候處理這個邏輯,不必定是打開小程序的時候執行這個邏輯。
    • 具體看業務須要,可是每每不少業務設計都是要用戶打開小程序的時候,來運行這個邏輯的。
  2. 小程序經過wx.login獲取微信的 code,而後將這個 code 發送給開發者服務器(咱們本身的開發服務器)。
  3. 開發者服務器接收到code 以後,會進行封裝處理,經過code2Session這個api 接口來獲取真正須要的微信用戶的登陸態session_keyopenidunionid小程序

    • 準確來講session_key纔是真正的微信登陸態信息,可是把 openidunionid加起來一塊兒理解,也能夠籠統地理解爲這些都是微信的登陸態信息。
  4. 而後須要開發者服務器本身生成一個自定義的登陸態(例如業務 token或者 session)來保存這些微信服務器返回來的微信登陸態相關信息(session_keyopenidunionid),而且作關聯處理,而後返回給小程序客戶端。微信小程序

    • 關聯處理就是你的自定義登陸態和微信的登陸態相關聯,這樣的話就不須要維護多個登陸態,只須要維護一個就能夠了。
    • 關聯處理以後須要將這個自定義登陸態信息保存起來,能夠放到數據庫或者本地文件或者 例如 redis 之類的緩存服務裏面,以便方便後續使用,而不須要每次都請求微信服務器(微信服務器對這個請求的頻率是有限制的)
    • 注意這裏不返回微信登陸態相關信息,只返回自定義的登陸態信息。
    • 自定義登陸態的信息不只能夠包含 token,也能夠包含一些用戶權限信息,或者其餘信息,由於是自定義的登陸態,維護也是很自定義的。
    • 通常自定義的登陸態的超時時長鬚要比微信的登陸態要長。
  5. 小程序客戶端接收到返回的自定義登陸態信息,從而判斷用戶是否登陸成功,登陸成功的話,就將自定義登陸態信息保存到本地的存儲。api

    • 本地的存儲能夠是微信小程序提供的 app.globaldata,也能夠是 localstoage,注意,小程序不支持 cookie
    • 保存到本地存儲的好處就是,後續使用的這個自定義登陸態就不須要再次跟服務器進行交互來獲取了,只須要調用本地存儲就好了,這裏是爲了優化性能和避免浪費資源。
  6. 小程序客戶端訪問業務接口的時候,攜帶以前保存到本地存儲的自定義登陸態信息進行對開發者服務器(業務接口服務器)訪問。
  7. 開發者服務器的業務接口接收到請求,而且請求裏面攜帶了自定義的登陸態,經過校驗以後,會返回相關信息。promise

    • 校驗是將小程序客戶端攜帶過來的自定義登陸態和開發者服務器緩存起來的自定義登陸態進行對比,會去確認是否和用戶的 openid或者 unionidsession_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就是這個。
  • 通常自定義登陸態的管理都會使用相似 redis 之類的東西來進行管理的,這裏也涉及到一個自定義登陸態的緩存策略,緩存起來,在必定時間內不須要從新建立自定義登陸態,達到優化性能的效果。
只有理解好官方的標準流程,才能更好地理解其餘流程,或者其餘人對官方流程的封裝和註解!

2、擴展微信小程序登陸流程

上面是基本的登陸流程理解,可是實際業務中仍是會有一些地方須要補充的,可是咱們理解的時候最好把他們分開,這樣會更清晰和簡單。

按照官方推薦的方式是使用自定義登陸態來管理整個微信小程序登陸流程的,雖說是經過一個自定義登陸態來管理,可是其實裏面是有變通的。

這裏有2種方式來作:

  1. 方式一:小程序打開的時候先檢查小程序本地是否有存儲的自定義登陸態,

    • 若是沒有,則表明是首次登陸,要自動執行完整的登陸流程,
    • 若是有,則須要判斷這個自定義登陸態是否過時,這裏判斷的方式有2種,一種是開發者服務器提供一個接口來檢查,一種是在這個自定義登陸態數據裏面加上過時時間,判斷是否過時。

      • 過時,則自動發起完整的登陸流程。
      • 不過時,就繼續使用本地保存的自定義登陸態。
  2. 方式二:小程序打開的時候先發起wx.checkSession檢查微信登陸態是否過時:

    1. 若是過時,則發起完整的登陸流程。
    2. 若是不過時,則繼續使用本地保存的自定義登陸態。(若是本地的自定義登陸態沒有的話,那麼也是要強制發起完整的登陸流程的)

上面說的方式都是打開小程序的時候作的,可是也要考慮到一種狀況,就是自定義登陸態在用戶使用小程序的過程當中過時了,那麼這時候也是須要強制執行完整的登陸流程的。

相對來講方式二比較好,方式二的好處是不須要小程序服務端來參與校驗,而是在小程序端調用API。這種方式其實是將維護登陸態的機制委託給了微信維護的session_key,開發者不須要在自定義的登陸態中保存有效期信息。騰訊雲開發的wafer項目便採起了這種方法。

3、繼續擴展微信小程序登陸流程

上面提到的方式二是在打開小程序的時候作的,這裏是在每次發起 HTTP 請求的時候作的,這個是不同的邏輯。

當小程序客戶端訪問接口的時候,開發者服務器返回說你的自定義登陸態過時了,你就須要從新發起完整的登陸,但這裏有2個點是須要注意的:

  1. 因爲 HTTP 是無狀態的,因此不能跟蹤狀態,發起 HTTP 請求而後服務器返回自定義登陸態過時的結果,而後就完結了,沒辦法暫存起原來的 HTTP 請求,以便當咱們有可用的自定義登陸態的時候,繼續使用。因此咱們須要在發起 HTTP 請求的時候作判斷,看是否須要發起完整的登陸流程。
  2. 在小程序裏面,常常會有訪問開發者服務器的狀況,可是若是每一個接口都須要這樣直接判斷的話,就會產生不少冗餘代碼,並且沒辦法維護,萬一登陸流程改變了,就要所有代碼改一遍了。

因此這裏就須要進行封裝一下,Random Notes這裏就提到了,思路是正確的,不過實現的話能夠按本身須要實現,他這裏有2個地方描述得很好,因此我搬過來借鑑了。

這是一個宏觀的,每一個請求都要檢查一下登陸態的邏輯圖:


圖片引用自:https://blog.imtouch.info

每一個請求都會檢查一次登陸態,不論是自定義登陸態仍是微信登陸態,反正只要發起跟開發者服務器交互的 HTTP 請求的以前都會檢查。

細分邏輯的話就會變成這樣:


圖片引用自:https://blog.imtouch.info

細分邏輯以後看起來會更加清晰,而且這裏的邏輯是微信登陸態和自定義登陸態都會檢查一遍,任何一個登陸態過時都會發起完整的登陸邏輯,其實我以爲這裏也能夠只判斷自定義登陸態的狀態也能夠的。

不過由此也帶來一個問題,就是若是一個頁面裏面有多個請求同時發起的話,那麼就會出現同時檢查到登陸態過時,而後同時發起登陸的狀況,這個問題可能會致使開發者服務器的校驗登陸數據出現問題,他這裏用到 promise.race 來解決,具體能夠看他的文章裏面介紹,我後面也會繼續寫一下這個處理的介紹。

參考文檔:

相關文章
相關標籤/搜索