我们的应用程序在每个公司都有公司和用途。每家公司都有X个许可证。我们使用的是类型化的会话类,该类包含公司的ID以及其他用户信息。我需要添加到我们的身份验证过程中,检查当前登录是否会超过公司的许可证。我相信这样做的方法是在所有与当前尝试登录的用户的companyId匹配的会话中计算所有公司ID,并将该计数与公司表中可用许可证的数量进行比较。这是一种有效的方法吗?如果是这样,请告诉我如何在所有会话中进行查询,因为我还没有弄清楚,而且我对ServiceStack还有点新鲜。
答案 0 :(得分:1)
ICacheClientExtended
界面现在支持GetKeysByPattern
API,可让您扫描实现该界面的缓存客户端上的匹配键。目前,这是通过以下方式实现的:
此API现在允许GetAllKeys()
上现有的新GetKeysStartingWith()
和ICacheClient
扩展方法扫描所有缓存键。
var prefix = IdUtils.CreateUrn<IAuthSession>(""); //= urn:iauthsession:
var sessionKeys = Cache.GetKeysStartingWith(sessionPattern).ToList();
var userSessions = Cache.GetValues<AuthUserSession>(sessionKeys);
var existingSessions = userSessions.Values.Where(x => x != null).ToList();
existingSessions
将包含活动用户会话列表。
效果取决于您拥有的活动会话数量,这取决于您网站的受欢迎程度。您可能希望保留每个公司的一组会话ID,而不是搜索所有键,而是将它们添加到Session or Auth Event中的集合中。
此新API可以从ServiceStack的 v4.0.45 + 获得,现在是available on MyGet。
最新的DynamoDbCacheClient现在位于MyGet上新的 ServiceStack.Aws NuGet包中,该包引用了AWS SDK中最新的 v3。* 包。< / p>
另一个选项是直接从ICacheClient
Caching provider访问它们,如果它支持完整扫描,例如如果您使用OrmLiteCacheClient
在RDBMS中存储会话,则可以使用以下命令访问所有缓存条目:
var sessionEntries = Db.Select<CacheEntry>(q =>
q.Where(x => x.Id.StartsWith("urn:iauthsession:")));
var userSessions = sessionEntries.Map(x =>
Db.Deserialize<AuthUserSession>(x.Data));
如果您正在使用Redis进行缓存,则可以使用:
var sessionKeys = Redis.SearchKeys("urn:iauthsession:*");
var sessions = Redis.GetValues<AuthUserSession>(sessionKeys);
另一种选择是通过注册您可以在Redis SET或RDBMS表中维护的自定义Session or Auth Event来维护每个公司的所有会话ID的列表。在同一个注册钩子中,您可以使用ICacheClient.GetAll
API验证他们拥有多少活动会话,并传入该公司的会话密钥,例如:
var sessions = Cache.GetAll<AuthUserSession>(companySessionKeys);
var activeSessions = sessions.Values.Where(x => x != null).ToList();
答案 1 :(得分:0)
一点速度检查:
我正在使用InMemoryAuthRepository,如果我在缓存中有1000个会话,并且我获取它们,则需要21毫秒。提取从4毫秒(1个会话)开始,到1000秒时最长为21毫秒。
sw.Restart();
IDictionary<string, IAuthSession> sessionList = cacheClient?.GetAll<IAuthSession>(cacheClient?.GetAllKeys());
sw.Stop();
totalMs += sw.ElapsedMilliseconds;
counter2speed.Add(counter, totalMs);