SAP Spartacus 的会话管理 Session Management
官網
從一開始,Spartacus 就包含了客戶端身份驗證和用戶身份驗證。 盡管這對于 Web 應用程序來說并不常見,但對于 Spartacus 來說是必須的,因為后者需要使用 OCC API。
客戶端身份驗證涉及代表已注銷用戶工作的 endpoint,例如注冊、重置密碼、以訪客身份下訂單和驗證地址。這些 endpoint 需要隨請求一起發送訪問令牌,并且需要按照 OAuth 規范定義的客戶端憑據流來檢索此訪問令牌。換句話說,某些 OCC 請求需要客戶端憑據流 - Client Credentials Flow,因此您需要在 OAuth 客戶端中啟用此流。
注意:在 OAuth 客戶端中啟用客戶端憑據流時,應始終將 ROLE_CLIENT 與 Spartacus OAuth 客戶端一起使用。永遠不要將 ROLE_TRUSTED_CLIENT 與 Spartacus 一起使用,因為它會顯著危害應用程序的安全性。
同時,用戶認證 - user authentication, 用于代表特定用戶資源發送的請求。例如,如果您想更新您的個人資料,您需要登錄。當您登錄時,服務器會確認您的憑據 - credentials, 并向應用程序返回訪問令牌。然后,此令牌將用于您帳戶上的所有請求,例如更新您的個人資料、修改購物車和結帳。
在 Spartacus 3.0 之前,客戶端身份驗證和用戶身份驗證的代碼都在 AuthModule 中,其中包括混合在一起的攔截器、服務和外觀方法。在 Spartacus 3.0 中,AuthModule 仍然包含客戶端和用戶身份驗證,但現在這是導入 UserAuthModule 和 ClientAuthModule 兩個模塊的結果。每個模塊負責一種類型的身份驗證。
此更改很重要,因為 Spartacus 默認構建為支持 OCC,但 Spartacus 不限于使用 OCC。 OCC API 需要為其接收的某些請求提供客戶端憑據,但這對于其他 API 并不常見,因此,客戶端和用戶身份驗證已分離,以便更輕松地與其他 API 一起使用。例如,如果您使用不需要客戶端身份驗證的其他 API,則可以只導入 UserAuthModule,而不是使用 AuthModule,并通過不包含 ClientAuthModule 來減小最終包的大小。
Authentication Flow
對用戶進行身份驗證是該模塊的主要職責。 先前版本的 Spartacus 使用自定義代碼來提供對資源所有者密碼流的支持,但 OAuth 指定了可在 Web 應用程序中使用的其他流。 為了支持這些額外的流程,Spartacus 3.0 不再將其自定義代碼用于資源所有者密碼流程,而是依賴于為此目的構建的第三方 angular-oauth2-oidc 庫,該庫也經過了良好的測試和認證。
身份驗證從 AuthService facade 開始,您可以在其中通過調用以下登錄方法之一來初始化流程:
- Resource Owner Password Flow 的 loginWithCredentials
- loginWithRedirect 用于隱式流或授權代碼流 - Implicit Flow or the Authorization Code Flow
然后 login 方法與 angular-oauth2-oidc 庫交互。 但是,這種交互始終通過 OAuthLibWrapperService,這是一個用于將外部庫與 Spartacus 代碼隔離的層。
Storing Tokens and User Identifiers
身份驗證后,從庫方法收到的令牌需要存儲在某個地方。 以前,這些代幣保存在 NgRx Store 中,但在 Spartacus 3.0 中,有專門的服務來保存數據。 該庫需要一個帶有類似于 localStorage 或 sessionStorage 的 API 的存儲機制,這是從 NgRx 切換到帶有流的服務來保存數據的主要原因。
對于身份驗證,通常僅存儲令牌及其元數據(例如到期時間和范圍)就足夠了。 但是,對于 OCC,還需要在登錄或注銷后設置緊密耦合的用戶 ID,以及在使用輔助服務模塊 (ASM) 時進行用戶模擬所需的用戶 ID。 在 Spartacus 3.0 之前,用戶 ID 與 NgRx 中的令牌保存在同一位置,并且由于之前的關聯,用戶 ID 仍保留在 UserAuthModule 中。 但是,令牌現在已與此模塊中的用戶標識符分開。 令牌及其元數據現在與 AuthStorageService 一起存儲,而用戶 ID 則擁有自己的專用 UserIdService。
Access Tokens in API Calls and Error Recovery
登錄用戶并存儲他們的訪問令牌和用戶 ID 后,就可以請求用戶的一些資源。為此,有必要在請求中將訪問令牌作為標頭傳遞。 在 Spartacus 中,這是通過 HTTP 攔截器實現的。
要使用訪問令牌豐富請求,您無需以任何方式標記請求。 AuthInterceptor 根據 URL 識別對 API 的請求。如果請求沒有 Authorization 標頭,并且匹配 API 路徑,則攔截器將標頭添加到請求中。為了更容易擴展攔截器,Spartacus 有自己的 AuthHttpHeaderService 幫助服務。在大多數情況下,擴展這一項服務就足夠了。
除了注入令牌之外,該攔截器還負責處理與授權相關的錯誤。在這種情況下,它首先嘗試恢復并重試請求,如果不可能,它完成注銷過程并將用戶重定向到登錄頁面。當請求因訪問令牌過期而失敗時,攔截器使用刷新令牌(如果存在)請求新的訪問令牌,然后使用新令牌重試失敗的請求。
第二個 TokenRevocationInterceptor 攔截器具有非常特殊的作用。對于在用戶注銷時撤銷令牌的調用,此攔截器添加了一個 Authorization 標頭。使用不同的 OAuth 服務器,您可能不需要提供此標頭,并且可以從您自己的 UserAuthModule 中刪除此攔截器。
Persisting Authentication Data in the Browser Storage
登錄后,您的令牌已被存儲并用于 API 調用,您刷新頁面,突然您不再登錄。 為避免此問題,AuthStatePersistenceService 將身份驗證數據(例如令牌和用戶 ID)同步到 瀏覽器存儲。
AuthStatePersistenceService 使用 StatePersistenceService 來與瀏覽器存儲同步數據。 UserIdService 中的用戶 ID、AuthStorageService 中的令牌和 AuthRedirectStorageService 中的重定向 URL 都同步到 localStorage。 每次數據發生變化時,都會保存在瀏覽器存儲中,應用啟動時從存儲中讀取到服務中。
@NgModule({// ClientAuthModule should always be imported after UserAuthModule because the ClientTokenInterceptor must be imported after the AuthInterceptor.// This way, the ClientTokenInterceptor is the first to handle 401 errors and attempt to refresh the client token.// If the request is not for the client token, the AuthInterceptor handles the refresh.imports: [CommonModule, UserAuthModule.forRoot(), ClientAuthModule.forRoot()],ClientAuthModule 應該總是在 UserAuthModule 之后導入,因為 ClientTokenInterceptor 必須在 AuthInterceptor 之后導入。
這樣,ClientTokenInterceptor首先處理401錯誤并嘗試刷新客戶端令牌。
如果請求不是針對客戶端令牌,則 AuthInterceptor 處理刷新。
參考:https://github.com/SAP/spartacus/pull/13280/files
總結
以上是生活随笔為你收集整理的SAP Spartacus 的会话管理 Session Management的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cortana是什么软件
- 下一篇: 新型基因疗法逆转猴子视力衰退,让眼睛重返