session - 负载平衡环境中的 ServiceStack session 处理

标签 session servicestack

我在我的一个项目中使用 ServiceStack 作为基础库。 我将我的应用程序分为两部分:API 和 WEB 应用程序,它们是单独的项目和存储库。

身份验证应该在 API 层上进行,并且应该缓存在那里。我在 API Server 中使用 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中,我正在保存 session ,该 session 存储在CacheEntry表中的Db中

我使用 apiurl/auth 通过 ajax 调用在 Web 应用程序中对用户进行身份验证,该调用返回带有 sessionIdAuthenticateResponse
我将此 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)以及 Web 和 Api 应用程序中提供的相应配置中获取 session 。

实现这一目标的最佳方法是什么?

但是我可以使用缓存客户端访问 session

//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);

});

这工作正常,我能够获取 session ,但是通过将其放入预请求过滤器中,会增加来 self 的 Web 应用程序的数据库调用(在每个请求上)。

是否有任何替代解决方案可以实现相同的目的?

提前致谢!!

最佳答案

如果您在同一域后面对多个 Web 应用程序进行负载平衡,则使用 distributed Caching Providers 中的任何一个就像 OrmLiteCacheClient 将在向任一应用程序发出请求时发送 ServiceStack 的 ss-id/ss-pid Cookie:

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

然后,只要每个应用程序配置了相同的 OrmLiteCacheClient,在一个应用程序中创建的 session 将在所有 3 个应用程序中可见。

您可以通过在 IRequest.Items 上设置它来阻止进一步的数据库访问以检索该请求的 session ,例如:

req.Items[Keywords.Session] = session;

然后,对该请求的 session 的任何访问都将从 IRequest 项字典中解析,而不是访问数据库。

另一个可供您在所有 3 个应用程序中进行身份验证的替代身份验证解决方案是使用无状态 JWT Auth Provider .

关于session - 负载平衡环境中的 ServiceStack session 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39831553/

相关文章:

servicestack - 有没有可能在 ServiceStack 中有两个 BaseURL WebHostUrl?

c# - 运行实现 ServiceStack.Redis 包的 C# 应用程序的先决条件

asp.net-mvc - 在 ServiceStack 服务中获取请求 URL、方案、主机名和端口

c# - ServiceStack.OrmLite 中的 ntext

java - 如何在 Vaadin 中获取所有 session

apache - Tomcat 7 - 我在哪里设置 'system properties' ?

hibernate 读取功能显示旧数据

session - Zend 框架 session 提前过期

php - 尝试传递数组时 SQL 不更新

servicestack - 自托管安全问题?