我需要存储用户朋友的列表,以便我可以在每个页面中使用它(无需每次都进行数据库查询)。
我想过SessionState
,但我认为这会很重,因为数据库很庞大。
所以我需要知道使用FormsAuthenticationTicket
是否是正确的方法呢?或者我也应该使用HttpOnly
Cookie吗?
答案 0 :(得分:3)
<强>的FormsAuthenticationTicket 强>
您可以通过以下方式将自定义数据存储在FormsAuthenticationTicket中:
string userData = "john smith;jane doe;bill murray";
HttpCookie cookie = FormsAuthentication.GetAuthCookie(user.UserName, true);
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
// Create a new FormsAuthenticationTicket that includes the custom user data
var newTicket = new FormsAuthenticationTicket(ticket.Version,
ticket.Name,
ticket.IssueDate,
ticket.Expiration,
true,
userData);
但是我会非常小心你在cookie中包含哪种数据。一件事存在安全问题,如果您在其中存储过多数据,则可能会产生无效的cookie。每次请求都会将Cookie发送到服务器。这只会增加请求的大小。
IIRC有4KB的大小限制(最大cookie大小)。因此,您可以存储在cookie中的数据量肯定是有限的。并且因为表单身份验证cookie已包含除用户数据之外的数据并且已加密,因此可用存储限制甚至更低。
我只会将它用于每次请求时需要的非常小的信息。当然不是可以增长的数据,例如朋友列表。而是标识符,我可以在服务器上使用它来查找内容。即使cookie被解密,这些值也毫无意义。
会话状态
我不会将这些数据存储在用户的电脑上。这样,这些数据将在他使用的每台PC /浏览器中分发。如果你想避免数据库往返,那么这将成为缓存的主要候选者。
老实说,我会将朋友列表存储在会话状态中。当记录器登录时,检索一次朋友列表并将其存储在会话中。更新好友列表后,只需更新会话数据即可。然后,每个子序列请求可以从会话状态中检索用户的朋友列表。
但显然你不想把它存放在会话中?可能是调查您的会话状态提供程序是否可以更改的好时机。例如,使用AppFabric缓存集群来存储会话状态。这样,它比默认的InProc或StateServer模式更容易扩展。
例如,您可以将数据提前一小时。超时后,朋友列表无效,会话中不再可用。您需要再次从数据库中检索(更新)列表。但是,这样您每小时只执行一次查询。
但是肯定在会话状态中存储一个简单的朋友列表不可能是一个大问题。还有什么存储在其中?当然不是整个数据库。
答案 1 :(得分:1)
您可以尝试使用SqlDependency存储到Cache对象中。
例如,你正在缓存以下查询的结果(这是一个简单的,我确定SqlDependecy会喜欢它),你也可以从中创建朋友“图”。
select u.UserId, u.FirstName, u.LastName, f.FriendId
from Users u
left join Friends f on f.UserId = u.UserId
如果您要更改好友列表,删除用户等,则升级无效,您无需担心从哪里更改,从管理员/ cms或Management Studio等单独的应用程序。
所以,基本上你在应用程序内存中只有一个朋友图,每个用户都可以非常快速地访问它们。
管理cookie中的数据可能非常困难,实际上我无法想象您将如何确定cookie中的朋友列表与数据库中的朋友列表相同。