4

以前也有人问过类似的问题,但我仍然没有答案,并且花了相当多的时间试图找到一个。

场景是这样的。我们有一个使用表单身份验证/LINQ-to-SQL 数据模型的 ASP.NET MVC 应用程序。

每个用户可以与 1 个或多个Accounts关联。登录后,应用程序会检查它们关联的帐户数量。

0 = 转到错误页面并让他们知道他们无权访问
1 = 设置用户数据以使用该帐户
2 或更多= 转到允许他们选择他们想要使用的帐户的页面(能够更改在他们访问期间)

您将如何存储这些信息?

此外,我想将此帐户用作我的控制器操作的基础。即他们访问的后续页面上的数据将与他们选择的帐户相关。

想到单例咳嗽,但不确定如何实现。

我目前正在研究的一种方法是一个基本控制器,所有控制器都将从该控制器继承

  1. 检查用户是否登录。
  2. 如果是,请检查他们是否选择了帐户
    • 否 - 将他们重定向到帐户选择页面
    • 是 - 继续原始请求

这样做的推荐/最佳实践方式是什么?

谢谢马尔科

4

2 回答 2

2

不要使用基本控制器。您可以使用操作过滤器完成此操作。这将为您提供拦截点,以检查他们是否已登录,是否选择了帐户,甚至将他们重定向到错误或帐户选择页面。您所要做的就是filterContext.Result在操作过滤器的OnActionExecuting方法中进行设置,以防止请求通过。在操作期间,您可以完全访问会话、临时数据、cookie 和整个 HttpContext,就像在控制器中一样。您还可以使用过滤器属性过滤器提供程序属性注入依赖项,这样就可以为您提供所需的任何数据访问权限。

就数据建模而言,我对 Linq to SQL 不太熟悉,但我认为正常的一对多应该可以解决问题:

User (1) <-------> (0..*) Account

public class User
{
    public virtual ICollection<Account> Accounts { get; protected internal set; }
}

public class Account
{
    public int UserId { get; protected internal set; }
    public virtual User User { get; protected internal set; }
}

更新:对不起,我误解了你所说的“商店”的意思。在 MVC 中,只有几种方法可以存储它 - Session、Cookie 和 Cache(以及 TempData,它只是短期会话)是最流行的选择。我的选择将取决于。Session 可能是最简单的,但是如果你部署到带有负载均衡器的服务器场,你需要考虑如果用户的 session 跳过物理机会发生什么。会话会保持不变吗?

正如杰里米所说,还有饼干。这里不用担心负载平衡,但语义比会话更难处理。例如,您必须先发送重定向以写入 cookie,然后才能读取它,而且我从不喜欢您必须添加过期 cookie 才能删除它的事实。由于此数据是您安全的一部分,您可能还想加密 cookie 值。

如果您使用缓存,则数据很可能最终仍会存在于内存中的某个位置,例如会话(除非您使用的是 SQL 会话提供程序)。缓存可能是我最后的选择,因为我们使用 Azure,而且它们的缓存不支持很多出色的 MVC 功能。您也有同样的问题,负载均衡器将用户移动到集群中的另一台机器,数据可能需要重新缓存。

无论哪种方式,您仍然应该为此使用操作过滤器,而不是基本的 Controller 类。

于 2012-05-15T07:17:31.200 回答
0

你在说什么类型的秤?我们是在谈论一百万用户还是几千?

我的第一个想法是创建一个字典,键是登录用户名(假设它是唯一的),值是关联帐户的数组(键或所有数据)。然后我会将字典放入缓存中。每当创建新关联时,它就会过期。

这种方法有几个问题。首先,新协会的创建速度有多快?如果它们不断被创建,那么缓存是一个有争议的问题。你总是要去数据库。其次,如果您有数百万用户/关联,将它们全部放入缓存可能不切实际。

另一种可能性是会话状态服务器,它专门用于存储关系。

还有一种可能性是每次都查询数据库,这取决于数据集的大小。当数据集增长到无法每次提取实时数据的规模时,您可以构建适合您需求的解决方案。

至于在请求之间持久化选定的帐户,选项是 cookie、url 或数据库(可以是用户上的一个字段,即 CurrentAccount,这种方法有点笨拙)。

由于您使用的是 MVC,因此我将使用 URL、路由和自定义路由约束,您可以创建一个包含帐户的 url。由于用户必须登录,因此您已经知道用户身份。

示例:http ://www.acme.com/{account}/edit/

检查用户是否登录可以在 Global.asax 中的操作过滤器或 Application_AuthenticateRequest 中处理。身份验证在 ASP.NET 中实现得相当好。哎呀,很多都是由 web.config 中的配置值驱动的。

确认身份验证后,可以以相同的方法进行帐户重定向。或者您可以等待并签入操作过滤器。

于 2012-05-15T15:21:54.173 回答