SAP Commerce Cloud UI 的用戶會話管理

這是 Jerry 2021 年的第 51 篇文章,也是汪子熙公衆號總共第 328 篇原創文章。

如無特殊說明,本公衆號介紹的 SAP Commerce Cloud UI,均指新一代基於 Spartacus 開源項目開發的 UI,而非傳統的基於 JSP 技術,同 Commerce 平臺耦合在一起的 Accelerator UI.

前文 從淘寶首頁登錄說起 提到過,淘寶網的用戶會話管理,通過瀏覽器的 Cookie 和服務器端的用戶會話對象來實現。

而 SAP Commerce Cloud UI,基於 100% API 驅動的無頭電商架構,Commerce 後臺將 Commerce 核心業務通過 OCC(Omni Commerce Connect) API 的方式暴露出來。藉助這些 API 和開源的 SAP Spartacus 庫,客戶可以自行開發具備個性化 UX 的電商網站。

關於 SAP Commerce Cloud Headless 架構的更多介紹,請參考我之前的文章:Jerry在2020 SAP全球技術大會的分享:SAP Spartacus技術介紹的文字版

SAP Commerce Cloud 有個名爲 Oauth2 的 extension,基於 OAuth 2.0 協議實現了用戶認證和令牌頒發/功能,支持 OAuth 2.0 協議定義的包括 Resource Owner Password Flow 在內的全部四種認證流。

SAP Commerce Cloud UI 扮演了 OAuth 2.0 認證框架中的客戶端 (Client) 角色,通過消費 SAP Commerce Oauth2 擴展提供的 OAuth 系列 API,實現用戶會話管理。

讓我們從最初始的用戶登錄場景說起。

輸入用戶名和密碼:

SAP Commerce Cloud UI 調用 Commerce OAuth2 API,endpoint 爲 /authorizationserver/oauth/token, 將用戶名,密碼,client_id 和 client_secret 去換取訪問令牌(Access Token)和刷新令牌(Refresh Token).

這裏的 SAP Commerce Cloud UI 作爲 OAuth 認證體系裏的客戶端,其 client_id 和 client_secret 在 Commerce Backoffice 裏配置:

服務器端驗證通過後,會頒發訪問令牌和刷新令牌,如下圖 access_token 和 refresh_token 字段所示:

SAP Commerce Cloud UI 在 OAuth 體系中扮演的角色是客戶端,通過訪問令牌,獲得訪問 Commerce 後臺服務器上的業務數據的許可。而刷新令牌,用於當訪問令牌過期時,由客戶端憑藉其換取新的訪問令牌。刷新令牌本身是一個憑證,表明持有其的客戶端,曾經通過 OAuth 認證,獲得了訪問受保護資源的許可,當通過刷新令牌再次請求新的訪問令牌時,客戶端不用再從頭開始走一遍 OAuth 認證的完整流程。

SAP Commerce Cloud 的訪問令牌和刷新令牌都有過期時間,有時也稱爲 TTL(Time-to-Live,存活時間),默認值分別爲12小時和30天。

而我們團隊的開發人員,在開發 SAP Commerce Cloud UI 用戶會話管理功能,進行各種邊界條件的測試時,爲了方便起見,通常將自己本地搭建的 Commerce 服務器上令牌的過期時間進行了調整。比如下圖的例子,二者分別調整爲30秒和60秒之後過期:

訪問令牌獲取之後,在接下來 Commerce Cloud UI 消費後臺 OCC API 時,會將其附加在 HTTP 請求的頭部字段裏:

如果此時訪問令牌已經過期,則該請求會收到服務器 401 錯誤的應答:

以及錯誤詳情 InvalidTokenError:Access token expired: IqQ-8cYzHV1gjQOpnYytHTFPt30

顯然這種偏技術的錯誤消息不應該顯示給用戶,幸運的是我們還有刷新令牌。此時,SAP Commerce Cloud UI 會將過期的訪問令牌,連同刷新令牌一齊發送給 Commerce 後臺,申請一個新的訪問令牌:

SAP Commerce Cloud UI 初次登錄申請令牌時,grant_type 的值爲 password;而訪問令牌過期,使用刷新令牌重新申請時,grant_type 的值應該填充爲 refresh_token.

如果刷新令牌的過期時間也到達了,該怎麼辦?沒有刷新令牌,也就無從獲取新的訪問令牌。因此,我們會將用戶重定向到登錄頁面,顯示一條“Session expired”的提示信息,讓其登錄之後,重新獲取訪問令牌和刷新令牌。

前文從淘寶首頁登錄說起曾經提到,我們在淘寶網上購物,如果不小心刷新了瀏覽器,只要客戶端存儲的 Cookie 尚未過期,就可仍然保持登錄狀態。這樣,客戶刷新之前的會話,比如添加商品到購物車,或者正在進行結帳的某一步,仍然處於有效狀態。

SAP Commerce Cloud UI 通過將訪問令牌持久化到瀏覽器的 Local Storage 中來實現上述場景。

每當用戶成功登錄後,我們將 Commerce 後臺服務器頒發的訪問令牌進行持久化存儲,保存到瀏覽器 Local Storage 中。

每次 SAP Commerce Cloud UI 初始化時,通過 Angular APP_INITIALIZER 這個注入令牌,我們開發了 AuthStatePersistenceService 服務,將瀏覽器本地存儲中的令牌同步到內存中。

採取這種設計後,即使用戶在購物過程中刷新了瀏覽器,SAP Commerce Cloud UI 重新加載後,從 Local Storage 中取出訪問令牌同步到內存中,接下來的用戶操作,繼續使用該令牌調用 Commerce OCC API,不會因瀏覽器刷新而中斷。

總結起來,SAP Commerce Cloud UI 有關訪問令牌和刷新令牌的使用場景如下:

(1) 用戶登錄後,SAP Commerce Cloud UI 將服務器頒發的訪問令牌存儲於內存中,並持久化到瀏覽器 Local Storage.

對於刷新令牌,出於安全性考慮,我們團隊實現時,僅將其維護在應用內存中,並不進行持久化操作。

(2) 當用戶操作 UI,觸發 API 調用後收到服務器返回的訪問令牌過期的錯誤之後,SAP Commerce Cloud UI 自動利用刷新令牌,申請新的訪問令牌;待拿到新的訪問令牌之後,使用該令牌重新調用之前因爲舊的訪問令牌過期而失敗的 API;這一系列機制對於用戶來說完全透明,用戶在界面上的操作不會受到任何影響。

(3) 如果用戶操作觸發的 API 調用收到的服務器返回爲刷新令牌過期,SAP Commerce Cloud UI 會暫存當前用戶瀏覽頁面的 URL,並將用戶重定向到登錄頁面;用戶重新登錄後,獲取到新的訪問令牌和刷新令牌,再被 SAP Commerce Cloud 重定向到刷新令牌過期時正在操作的頁面。

本文簡單介紹了 SAP Commerce Cloud UI 用戶會話管理的基本實現原理和支持的場景。對其技術實現感興趣的朋友,可以查閱我們團隊發佈在 Github 上的文檔,感謝閱讀。

https://sap.github.io/spartacus-docs/session-management

更多閱讀

更多Jerry的原創文章,盡在:"汪子熙":


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章