MVC 4:如何在 IIS 重启后保持会话和 cookie 仍然有效?

Posted

技术标签:

【中文标题】MVC 4:如何在 IIS 重启后保持会话和 cookie 仍然有效?【英文标题】:MVC 4: How to maintain sessions and cookies to be still valid after IIS restart? 【发布时间】:2017-06-24 10:19:15 【问题描述】:

似乎我的登录会话(使用简单成员)和 cookie(验证令牌)在 IIS 服务器重新启动后无效。这对我来说是个问题,如果用户在事务中间然后服务器重新启动,用户必须重新填写表单并再次执行,也可能是事务在中间中断时出现的一些代码问题过程。

如何让它们在服务器重启后仍然有效?

这是我的 web.config:

<membership />
...
<sessionState mode="InProc" cookieless="false" timeout="2880" />
...
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication> 
...
<staticContent>
  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
  <remove fileExtension=".woff" />
  <remove fileExtension=".woff2" />
  <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
  <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
</staticContent>

更新

我尝试使用 SQLServer 来存储会话状态。然后出现了新问题,我不能使用ViewBag,因为它不是Serializable

还有其他方法可以实现吗?

【问题讨论】:

会话存储在服务器上,因此如果服务器重新启动,会话就会丢失,但是您可以使用 cookie 来存储数据,因为它存储在客户端计算机上。 您是否尝试过在 web.config 中设置 Machinekey 而不是使用自动生成类型?重新启动时,IIS 将生成一个用于加密/解密登录 cookie 的新密钥,阻止它读取现有的 cookie。通过设置MachineKey,重启后仍然可以读取cookie。 ViewBagsession 没有任何关系,除非您将ViewBag 存储在Session 中,这当然不是一个好习惯。 在客户端...只需寻找适当的响应...如果没有,则在新表单中重新填写数据。他们不会去任何地方...我认为您不需要为此做出详尽的回应,对吗?如果是这样,那么您可能需要在问题中提供更多详细信息,说明原因,因为这听起来可能是一个特定的需求。 您在会话中搅拌的是什么类型的?数据表?列表? 【参考方案1】:

也许我迟到了,但我正在做下一步以在 iisreset 后保持会话。我正在使用 IIS 10,但也许它可以在其他版本中工作:

    在 IIS 配置管理器 (InetMgr.exe) 上单击会话状态

    选择“状态服务器”并点击应用

    启动 Windows 服务“ASP.NET 状态服务”(如果要在重新启动计算机后使用,可以将其更改为自动)。

之后,您可以重置 iis 并保持会话。

【讨论】:

【参考方案2】:

只是你做不到,使用键值数据库是将会话保存在内存中的最佳选择(如redis),它比关系数据库如sql server快得多。

将数据保存在本地存储或 cookie 中可能会导致数据丢失或安全问题。

【讨论】:

【参考方案3】:

localStorage(自己的浏览器存储)可用于在本地存储数据,而无需使用 cookie。

这里是 W3Schools 链接:https://www.w3schools.com/html/html5_webstorage.asp

【讨论】:

【参考方案4】:

将会话保存在一个集群数据库(master-master)中,这样一个失败的时候另一个会接管。

【讨论】:

【参考方案5】:

如果您在尝试保持会话时收到有关 viewbag 的错误,则意味着您将 viewbag 存储在会话中。你真的需要吗?我认为您应该避免将 viewbag 存储在会话中,如果您真的想这样做,请使用您自己的可序列化自定义类。可能是一个通用字典也已经可以满足您的需求......然后将您的会话持久化到数据库,或者如果您想重新发明***,请实现您的自定义Session-State Store Provider。一般来说,使用 session 来存储信息从来都不是一件好事 实践的原因很多,主要是服务器重启时你的数据丢失了。据我所知,在您的网络应用程序中,您正在使用会话来存储发布的数据,正确的做法是中继到 viewmodel 类。

【讨论】:

【参考方案6】:

可能您必须将会话存储在数据库中,希望本教程对您有所帮助 https://msdn.microsoft.com/en-us/library/ms178586(v=vs.140).aspx

【讨论】:

【参考方案7】:

没有办法实现这个 AFAIK。您始终可以使用DatabaseFile 来保留会话和cookie 值。

您的想法可能是序列化您想要保留在SessionCookie 中的对象。有很多工具可以为您进行序列化,我使用newtonsoft。然后将其作为字符串与会话密钥一起存储在数据库中。

要取回它,您可以简单地根据会话密钥触发查询,获取字符串并反序列化它,您就完成了:)

【讨论】:

我听说过类似cookieless="true"cookieless="UseCookies" 之类的内容?这对我的网站有帮助吗? cookieless 指定会话 ID 的存储位置。如果为真则将通过 url 发送,如果为假则将存储在cookies 中。 SessionId 被 Web 服务器用来为当前用户选择合适的会话对象。所以这不是你的情况的解决方案。 所以我的选择只有两个。数据库或文件,你有例子参考吗? 例子是什么? 如何将持久会话存储在文件或数据库中的示例。我实际上更喜欢文件,因为它的性能成本不会很高,不是吗?【参考方案8】:

Cookie 存储在客户端浏览器中,并在每次请求时发送到服务器。因此,cookie 在 IIS 重新启动或 AppDomain 回收时可用。

默认情况下,会话数据不会在 AppDomain 回收或 IIS 重新启动时保留。实现这一点的唯一方法是使用会话状态提供程序,例如 SQL 服务器的提供程序。

为此,会话状态提供程序需要能够序列化/反序列化您的数据,以便从数据库中持久化和恢复它,这意味着您需要使用可在会话中序列化的类型。

您可以更改您的代码以使用其他可序列化的类型或将您的数据存储在 cookie 中。

【讨论】:

【参考方案9】:

默认情况下,会话数据存储在内存中。因此,当 IIS 重新启动时,您会丢失它。您可以考虑使用其他 proc sessionstate 提供程序来存储数据,例如数据库,会话状态服务。

【讨论】:

以上是关于MVC 4:如何在 IIS 重启后保持会话和 cookie 仍然有效?的主要内容,如果未能解决你的问题,请参考以下文章

服务器断开连接后如何在 Spring MVC 中保持客户端会话处于活动状态

服务器重新启动时如何在节点 js 中保持持久会话?

如何防止 Ajax 调用使会话保持活动状态?

Spring Security、Spring MVC 和登录会话

在 IIS 上部署后从数据库返回的 MVC 4.0 .NET 应用程序和值

windows7里的IIS里怎么设置session会话超时时间?