代码之家  ›  专栏  ›  技术社区  ›  Dan

ASP.Net会话超时检测:Session.IsNewSession和sessioncokie检测是最好的方法吗?

  •  7
  • Dan  · 技术社区  · 16 年前

    当我的ASP.Net会话超时(以及表单身份验证)并且我试图访问某个页面时,会自动重定向到我的默认login.aspx页面。

    在加载页面之前,我需要确定这是否是超时情况,如果是,请重定向到timeout.aspx。

    下面的文章指定,如果为true,并且存在一个可缓存的cookie,那么您就有超时的情况。

    然而,在我的测试中,我遇到了这样的情况:我超时并尝试再次登录,而IsNewSession等于true,sessionId cookie仍在运行(因为它在整个浏览器会话中保持不变),因此它说我在尝试重新登录时再次超时。

    有没有更好的方法来做这些?

    技术说明 here here .

    在我的“global.asax”文件中,我有:

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
            // Check if session state is enabled in web.config
            if (Context.Session == null) return;
    
            if (Session["user"] == null) 
            {
                if (Session.IsNewSession)
                {                    
                    HttpCookie sessionCookie = Request.Cookies["ASP.NET_SessionId"];
                    if ((null != sessionCookie) && !string.IsNullOrEmpty(sessionCookie.Value))
                    {
                        /* Session Timeout! */
                        FormsAuthentication.SignOut(); //just in case not done yet
                        Session.Abandon();
                        Response.Redirect("timeout.aspx");
                    }
                    else
                    {
                        // Cookie didn't exist - must be a brand new login
                        return;
                    }
                }
                else
                {
                    // If there is no session data and the session is not new then it must be the postback of the login screen.
                    if ((HttpContext.Current.Request.Path.ToLower().LastIndexOf("/login.aspx") >= 0) && (Request.HttpMethod == "POST"))
                    {
                        return;
                    }
                }
            }    
    }
    
    2 回复  |  直到 16 年前
        1
  •  7
  •   AnthonyWJones    16 年前

    您试图区分超时会话和手动注销的会话?

    您的问题是,由于会话数据已不存在,因此您需要继续执行的操作是,传入的新请求已创建了一个新会话,传入的请求带有会话ID cookie(表示它以前已登录)。

    有两种方法。

    饼干:

    首先在登录页面中,您可以创建一个额外的cookie,指示用户的登录状态。当用户手动注销时,将修改cookie值以指示注销。会话超时后的请求将 IsNewSession true还会有一个登录状态cookie,显示用户仍在登录,从而指示用户没有手动选择注销。

    数据库:

    第二种方法是将sessionid与登录状态一起存储在DB表中。登录成功后,将sessionID输入LoggedOnSessions表。当用户手动注销时,从表中删除sessionID。因此,如果存在超时,则可以在表中查找会话ID(此时可能还应该删除该ID)。

    出于内务管理的目的,您应该包含一个expiry datetime字段,该字段的设置时间要比任何实际的登录周期(例如一周)长得多。定期(如每周)删除表中已过期的条目。

    我最喜欢的是数据库方法,我讨厌设置cookie,因为每次请求都会发送cookie,但很少需要。

        2
  •  -1
  •   MachibestMachibest    15 年前

    您还可以在标记下面的web.config文件中查找 身份验证 . 应该是这样的:

    <authentication mode="Windows">
      <forms defaultUrl="Default.aspx" loginUrl="Login.aspx" name=".aspxAuth">
      </forms>
    </authentication>
    

    注意属性 模式 ,它可能会在web.config文件中显示窗体而不是窗口。在这种情况下,如果您丢失会话,然后单击任何链接(比方说SalesChart.aspx),ASP.NET将直接带您登录Login.aspx codebhind,而不是SalesChart.aspx codebhind,后者特别烦人。

    如果您尝试Windows模式,每次都会转到请求的页面(SalesChart.aspx),然后自行决定会话丢失时要采取的操作。