2016-10-03 72 views
3

我在我的一個項目中使用ServiceStack作爲基礎庫。 我已經在兩個部分API和WEB應用程序中構建了我的應用程序,它們是獨立的項目和存儲庫。負載平衡環境中的ServiceStack會話處理

身份驗證應該發生在API層,它應該被緩存在那裏。我在API服務器中使用Ormlite緩存客戶端。

在API AppHost.cs

var dbFactory = new OrmLiteConnectionFactory("ConnectionString",SqlServerDialect.Provider); 
container.RegisterAs<OrmLiteCacheClient, ICacheClient>(); 
container.Resolve<ICacheClient>().InitSchema(); 
Plugins.Add(new AuthFeature(() => new APISession(), 
    new IAuthProvider[] { 
    new APICredentialsAuthProvider(new AppSettings()) 
})); 

在APICredentialsAuthProvider我現在的儲蓄它獲取存儲在分貝CacheEntry

我使用apiurl/auth通過Ajax調用驗證在Web應用程序的用戶會話其返回AuthenticateResponsesessionId與它。
我正在將此sessionId更新爲cookie,作爲s-id,稍後在預先請求過濾器中根據請求類型將其更新爲ss-idss-pid

//Inside Web application apphost 
this.PreRequestFilters.Add((req, res) => 
{ 
    System.Net.Cookie cookie = req.Cookies["s-id"]; 
    req.Cookies["ss-id"] = cookie; 
    req.SetSessionId(cookie.Value) 
}); 

這種方法不獲取從緩存中的會話是Ormlite在我的情況,並在網站和API應用程序提供相應的配置。

達到此目的的最佳方法是什麼?

但是我能夠通過使用緩存客戶端

//Inside Web application apphost 
this.PreRequestFilters.Add((req, res) => 
{ 
    System.Net.Cookie cookie = req.Cookies["s-id"]; 
    req.Cookies["ss-id"] = cookie; 
    req.SetSessionId(cookie.Value); 
APISession cachedSession = GetCacheClient(req).Get<APISession(SessionFeature.GetSessionKey(cookie.Value)); 
WEBSession session.PopulateWith<WEBSession, APISession>(cachedSession); 

}); 

這工作得很好,我能夠獲取會話,而是將這一預請求過濾器訪問會話增加了從數據庫調用我的Web應用程序(每個請求)。

是否有任何替代解決方案可以實現相同?

在此先感謝!

回答

3

如果你是負載平衡多個Web應用程序然後使用任何distributed Caching ProvidersOrmLiteCacheClient將發送ServiceStack的ss-id/ss-pid餅乾發出請求時,無論是應用程序的同一域中的背後:

http://example.org/app1 -> http://internal:8001/ 
        /app2 -> http://internal:8002/ 
        /app3 -> http://internal:8003/      

然後,只要每個應用都配置了相同的OrmLiteCacheClient,則在一個應用中創建的會話將在所有3個應用中可見。

您可以防止用於檢索該請求的會話通過設置它IRequest.Items,進一步DB訪問,例如:

req.Items[Keywords.Session] = session; 

然後到會議的任何訪問該請求將從IRequest項字典來解決,而不是擊中數據庫。

另一個可以讓你在所有3個應用程序中進行身份驗證的Auth解決方案是使用無狀態的JWT Auth Provider