【问题标题】:What does it mean if my Asp.Net session has IsNewSession == true, and should I care?如果我的 Asp.Net 会话具有 IsNewSession == true 是什么意思,我应该关心吗?
【发布时间】:2015-12-05 22:51:15
【问题描述】:

首先,这是我继承的代码,编写它的人不再在这里,也无法质疑。

我让生产中的用户对随机退出我们的 Asp.Net MVC 应用程序感到恼火(根据参考资料,我们的 MVC 库是第 5 版)。在代码和网站中徘徊了一段时间后,我想我已经将用户看到的内容隔离到以下代码:

public class SessionExpireFilterAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext ctx = HttpContext.Current;

        // check if session is supported
        if (ctx.Session != null)
        {

            // check if a new session id was generated
            if (ctx.Session.IsNewSession)
            {

                // If it says it is a new session, but an existing cookie exists, then it must
                // have timed out
                string sessionCookie = ctx.Request.Headers["Cookie"];
                if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    SessionVariables.Current.User = null;
                    FormsAuthentication.SignOut();

                    filterContext.Result = new RedirectResult("~/Account/Logon");

                    return;
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

我不完全确定为什么需要此代码(您为什么要将其归因而不是使其全局化),但我在搜索中看到互联网上此代码的变体,但没有说明您想要的原因它。

不管怎样,它已经在我们的代码库中,我们遇到的问题似乎是,如果用户在窗口中闲置一小段时间然后他们做某事,ctx.Session 不为空,而是ctx.Session.IsNewSession 是真的。

这对我来说意味着,出于某种原因,Asp.net 决定该用户需要为他们启动一个全新的会话,并且由于我们不知道该用户是谁(因为他们的所有会话数据都已消失......一个新的会话)我们需要注销他们并让他们重新登录。

这一切似乎都是合乎逻辑的,只是我终于能够在IsNewSession if 语句中打断点。对我来说奇怪的是,我的 Session 实际上看起来 100% 已填写(并且填写正确)。这意味着它正确地知道我是谁,以及只有在您成功登录后才会放入会话中的所有其他信息。

此外,ctx.User.Identity.IsAuthenticated 是真的,它有正确的登录名。

一切似乎都表明我有一个有效的会话,但由于这段代码正在做出设计决定,即如果 Asp.Net 创建一个新会话,我必须注销,用户将被注销。

所以我的问题是:

  1. Session.IsNewSession 的实际含义是什么?
  2. IsNewSession 为真时始终将用户注销是否正确?
  3. 只要用户被列为已通过身份验证并具有有效的会话数据,不注销用户是否有任何后果?
  4. 是什么导致 Asp.Net 创建新会话但仍重复使用以前的会话数据?
  5. 我对会话过期的理解是它是由提供程序层引起的,因为如果会话过期,Asp.Net 甚至不会有任何会话数据。不是这样吗?

顺便说一下,我们目前使用 Redis 作为我们的会话存储。此外,如果相关应用程序托管在 Azure 网站上(我不确定这会如何影响会话到期)。

【问题讨论】:

  • 简单来说,就是当现有 会话存在但已超时时启动了一个新会话。当包含先前会话的 cookie 被发送回 Web 服务器时,该会话已过期,因此会构建一个新会话(因此 IsNewSession==true),因为该会话 ID 与构建的新会话 ID 不同。
  • 我想我应该添加 FormsAuthentication.Timeout 显示 8 小时超时,但 htis 在最初登录后大约 5-10 分钟发生。所以理论上会话不应该在那个时间超时期间对吗?
  • FormsAuthentication 超时与会话超时不同。
  • 您是否检查过网站上发生某种错误或内容更改的可能性,其中任何一种都会破坏当前会话?
  • 我没有,但这又回到了我最初的问题是,如果前一个会话由于错误或内容更改而超时,我是否应该关心一个新会话?据推测,当这些情况发生时,用户应该保持登录状态,尤其是在进程外会话状态存储(如 redis)的情况下?如果不是 100% 使用此代码,任何负载平衡似乎都会完全破坏用户会话

标签: asp.net session


【解决方案1】:

只要没有当前会话的浏览器导航到站点,ASP.NET 就会创建一个新会话。所以即使有人没有登录,他们仍然会有一个会话。同样,如果一个会话过期,则下次浏览器发出请求时将创建一个新会话。这个新会话中不会存储“会话数据”,但ctx.Session 不会为空。此外,如果您有多个服务器,并且负载均衡器恰好将用户路由到不同的服务器,那么该新服务器将尝试启动新会话。

会话状态与身份验证状态分开跟踪,这意味着一个可以过期而另一个仍然有效。对于编写良好的应用程序,这通常不会导致任何问题。但是,一些应用程序在登录时将信息预加载到会话中,并将会话视为一种在会话长度内保存此信息的缓存。或者,当用户执行某些操作时,他们将在会话上设置值,并且以后的操作会期望这些值在会话上,因为用户应该已经浏览了那些早期的操作才能到达那里。 (例如,一个向导界面,其中每个步骤都将值保存到会话中,以供用户在最后一步单击“完成”时使用。)

您的应用程序可能在某些时候期望数据在不存在的会话上,而开发人员意识到它不存在,因为 ASP.NET 已自动更新会话,丢失了所有先前设置会话数据。他们没有重新设计他们对会话数据的使用,而是选择这样做,以便在他们失去会话时,他们也会迫使用户回到一个理智的起始位置,页面不会因为会话而以奇怪的方式中断- 存储的数据丢失了。

【讨论】:

  • 写得非常全面的答案!!
猜你喜欢
  • 2021-08-07
  • 2010-10-12
  • 2016-03-18
  • 1970-01-01
  • 2016-10-12
  • 2016-03-01
  • 2021-07-14
  • 1970-01-01
  • 2012-08-23
相关资源
最近更新 更多