2016-10-03 69 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