【问题标题】:Cookie persistence and best practiceCookie 持久性和最佳实践
【发布时间】:2013-10-15 14:44:50
【问题描述】:

在我们的应用程序中有两种类型的用户,我们称他们为AlphaBeta 用户。这些用户中的每一个都会看到不同类型的工具栏/菜单。

我们决定使用 cookie 来跟踪这一点。我们的大部分页面要么是Alpha 页面,要么是Beta 页面,还有一些AlphaBeta 用户共享的常见页面。因此,在我们知道用户类型(AlphaBeta)的应用程序的每个视图中,我们都有以下代码:

HttpCookie isAlphaCookie = new HttpCookie("IsAlpha", "false"); // or true
HttpCookie isBetaCookie = new HttpCookie("IsBeta", "true"); // or false

isAlphaCookie.Expires = DateTime.MaxValue;
isBetaCookie.Expires = DateTime.MaxValue;

Response.Cookies.Add(isAlphaCookie);
Response.Cookies.Add(isBetaCookie);

这样的想法是,在普通页面中,我们不设置任何 cookie,而是依靠先前设置的 cookie 来确定要加载哪个工具栏。因此,这两个 cookie 在我们已知页面中设置为truefalse,然后我们在控制器方法中读取它们,该方法加载我们的工具栏,如下所示:

HeaderViewModel header = new HeaderViewModel
{
    FirstName = UserProfile.CurrentUser.FirstName,
    LastName = UserProfile.CurrentUser.LastName,
    ImageUrl = null,
    OrganisationName = UserProfile.CurrentUser.OrganisationName,
    OrganisationUrl = UserProfile.CurrentUser.OrganisationUrl,
    ShowAlphaToolbar = bool.Parse(Request.Cookies["IsAlpha"].Value),
    ShowBetaToolbar = bool.Parse(Request.Cookies["IsBeta"].Value),
    ShowPublicToolbar = false
};

return PartialView("Common/_Header", header);

从阅读如何读取/写入 cookie 来看,这似乎是正确的方法;将cookie写入Response对象并从Request对象读取cookie。

我遇到的问题是,当我进入加载工具栏的控制器方法时,IsAlphaIsBeta cookie 的值都是空字符串,这会破坏应用程序。

我已确认 cookie 在Request 中读取之前已设置在Response 中。

我想知道我是否在这里遗漏了一些基本的东西。

【问题讨论】:

  • 尝试使用一些浏览器工具或 Fiddler 来查看 cookie 是否真的被浏览器存储并在请求期间发送回服务器。
  • 如何调用包含工具栏的部分操作?通过 ajax 还是通过 @Html.RenderAction()?
  • 检查 cookie 中设置的ExpiryDate
  • @Ankit 工具栏使用@Html.Action("LoadHeader", "Profile") 加载。如果这对我不起作用,您能建议一种替代方法吗?
  • 您会保护这些cookies吗?根据您上面所说,用户更改 cookie 值并更改其用户类型将是微不足道的。看看加密字符串,或者给它添加一个 MAC,这样它就不会被篡改。

标签: c# asp.net-mvc cookies


【解决方案1】:

我只希望您的假设“在常见页面中,我们不设置任何 cookie,并依靠先前设置的 cookie 来确定要加载的工具栏”如果您调用这些部分操作(您将其称为“公共页面”我猜是通过 Ajax 调用。如果你正在使用

@Html.RenderAction('nameOfaAtion')

那么我认为你所拥有的一切都行不通。

原因是您的主要操作和部分操作都在同一个 Http 请求周期内执行,因此您尝试从公共页面中的请求对象访问的 cookie 尚未作为请求的一部分。

编辑

正如我所见,您正在对每个页面上的 cookie 进行硬编码,所以猜猜您也可以执行以下操作。最初不是您尝试做的方式,但我认为它会做与您尝试相同的事情。

在您的页面中将部分视图调用更改为这样。

@Html.Action("LoadHeader", "Profile", new{IsAlpha=False, IsBeta=true});

然后改变LoadHeader动作的签名来接收这两个额外的参数

public ViewAction LoadHeader(bool IsAlpha, Bool IsBeta)

然后用 viewModel Initialization 改变两行如下。

ShowAlphaToolbar = IsAlpha, 
ShowBetaToolbar = IsBeta,

【讨论】:

  • 使用@Html.Action("LoadHeader", "Profile")加载工具栏。如果这对我不起作用,您能建议一种替代方法吗?
  • 或者最好使用 ajax 来加载这个局部视图。我想你不需要更改任何其他内容。
  • 我在上面编辑的答案中看到的问题是我在我的 OP 中描述的“常见”页面。我不会在这些页面中设置任何参数(IsAlpha 或 IsBeta),并且需要知道在前一页中设置了哪些值。我很想做这样的事情,但我认为这不可能。我正在考虑使用CookiesTempData 的组合。我没有全面使用TempData 的原因是我们使用了多个Azure 实例,并且无法确定我们将TempData 设置在哪个实例上。但是如果在一个请求中使用TempData,我们应该没问题
猜你喜欢
  • 2018-09-17
  • 2011-08-13
  • 2020-09-26
  • 2020-10-02
  • 1970-01-01
  • 2012-08-09
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
相关资源
最近更新 更多