6

我正在开发一个 Asp.net(MVC,但这并不重要)应用程序。我有一个自定义 IHttpModule 负责 PostAuthenticateRequest 更改用户主体和身份。

用户登录时,我将 UserID 和 UserName 存储在身份验证 cookie 中。我有一个 IUser(由 DAO 和业务对象层实现,每个都有自己的附加成员),我需要整个业务服务类。当用户想要任何东西时,我必须提供 IUser 对象实例(通常来自业务对象层),因此提供身份验证票证的 ID 是不够的。

所以我正在考虑如何以及在哪里最好地持久登录用户的 IUser 数据?

  1. 我不想每次都从数据库中获取它(基于身份验证票的 UserID 数据)
  2. 我无法将它存储在 Session 中,因为我必须在 PostAuthenticateRequest 中工作,其中 Session 尚未准备好
  3. 我希望将所有功能封装在我的自定义 IHttpModule 中

我看到的选择:

  • 缓存
  • 曲奇饼
  • (会话) - 通过从 PostAuthenticateRequest 移动到 PostAcquireRequestState 事件并在那里更改主体/身份,但我想避免这种情况

似乎使事情复杂化的过程是:

  1. 用户登录,从数据库中获取用户数据并以某种方式持久化以供以后请求
  2. 用户注销,用户数据必须自动从持久媒体中删除
  3. 用户更改自己的个人资料,必须丢弃用户数据并在下一次来自数据库的请求时重新读取

我不希望所有这些都由 HttpModule(如果可能)自动处理,以消除开发人员忘记重置这些东西的错误。

我也不想要的是写/读一些硬编码的变量/键并在应用程序的其他部分操作它们。这只会带来技术债务。

问题

  1. 你有什么建议?
  2. SO如何在请求之间保留用户数据?
4

1 回答 1

4

鉴于您的要求,我想最好的解决方案是从 cookie 中检索 ID 并使用它来索引 Http Cache (HttpContext.Current.Cache)。

如果您想维护用户访问它的方式,请将缓存包装在“UserCache”对象中。该对象可以由 HttpModule 构造并存储为(等待它...)缓存本身内的单例,或者更好的是,仅在需要从 http 缓存中提取时构造。这取决于您需要访问它的位置以及 HttpContext.Current.Cache 是否直接可用。惰性实现如下。

同样,这是为了清楚起见,并不是我实际实现它的方式。

public class UserCache
{
  public IUser GetUser(object userKey)
  {
    return HttpContext.Current.Cache[userKey];
  }

  public void AddUser(object userKey, IUser user)
  {
    /* this could pull the key from the user object as well. */
    HttpContext.Current.Cache.Add(/* add the object with key and a sliding expiration that is slightly greater than session timeout */);
  }

  public void ExpireUser(object userKey)
  {
    HttpContext.Current.Cache.Remove(userKey);
  }

  /* If you don't want to do SQL cache dependency */
  public void UpdateUser(object userKey, IUser user)
  {
    HttpContext.Current.Cache.Insert(/* ... */);
  }
}

使用默认的缓存机制(或者更好的是由 DI 提供的缓存机制,因此您不依赖于实现),您可以设置过期时间以自动从缓存中删除用户,如评论中所述。您可以将缓存设置为依赖于 SQL 服务器更新以及处理更新或手动更新它作为服务的一部分以保存更改。

有关默认缓存的更多信息,请参见此处。有关缓存依赖项的更多信息,请参见此处

在 HttpModule 本身中,我想您可以在 EndRequest 事件中做一些魔术来查看请求是否经过身份验证,然后根据 cookie 将用户注销,但我不确定这是否可行,因为我从未尝试过它。您可能想从 1.1 天的 WAY 开始查看 MSDN 上的这篇文章,看看它是否回答了您正在尝试解决的一些问题。

至于 SO 架构以及他们如何做到这一点,我想他们会在需要时加载它,因为他们始终将大部分数据库保存在 RAM 中(http://highscalability.com/stack-overflow-architecture)。

于 2009-08-12T03:23:09.987 回答