【问题标题】:Session_End in Global.asax.cs not firingGlobal.asax.cs 中的 Session_End 未触发
【发布时间】:2019-03-01 19:57:10
【问题描述】:

我有一个 Asp.net Web 应用程序,我在其中使用 FormsAuthentication 进行用户登录。

我想防止同一用户同时多次登录。 为此,我将 FormsAuthentication 超时设置为 15 分钟,将 Session.timeout 设置为 15 分钟。

当用户在未注销的情况下关闭浏览器,或者如果用户处于非活动状态 15 分钟,则不会触发 global.asax.cs 文件中的 Session_End() 事件。我想更新 Session_End() 事件中的数据库字段。

登录代码:

if (Membership.ValidateUser(username, password))
                {
                    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                        1,
                        username,
                        DateTime.Now,
                        DateTime.Now.AddMinutes(15),
                        false,
                        FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1"));

                    // Now encrypt the ticket.
                    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                    // Create a cookie and add the encrypted ticket to the cookie as data.
                    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    context.Response.Cookies.Add(authCookie);

context.Response.Redirect("/HomePage", false);
}

Global.asax.cs:

 protected void Session_Start(Object sender, EventArgs e)
    {
        Session["init"] = 0;
        Session.Timeout = 15;
     }
    protected void Session_End(Object sender, EventArgs e)
    {
        PersonObject person = new PersonObject();
       // calling the function to update entry in database
        person.ResetUserLoginStatus(HttpContext.Current.User.Identity.Name);
    }

更新数据库条目的功能:

 public bool ResetUserLoginStatus( string username="")
    {
        string sql = "UPDATE Person SET IsLogged=0 WHERE Person =  @Person";
        PersonObject person = new PersonObject();
        object id = person.ExecuteScalar(sql, new Dictionary<string, object>() {
            { "Person", (!string.IsNullOrEmpty(username)?username:User.Name )}
        }, "Person");

        return true;
    }

Web.config:

<authentication mode="Forms">
  <forms loginUrl="/Security/Login.ashx/Home" name="SecurityCookie" timeout="15" slidingExpiration="true">
  </forms>
</authentication>

<sessionState timeout="15" mode="InProc"></sessionState>

问题是,当浏览器关闭时,ResetUserLoginStatus() 方法没有被调用,我无法将我的值重置为 0。由于该字段尚未重置为 0,因此该用户将无法重新登录。

请提出建议。

【问题讨论】:

  • 请发布您的代码
  • 关闭浏览器永远不会触发它。它会在至少 15 分钟超时后发生,可能会更长。
  • 是的。浏览器关闭后,我等了 30 分钟。但它仍然没有触发 Session_End()

标签: c# asp.net session forms-authentication


【解决方案1】:

Session_End 实际上并没有那么有用或可靠。一方面,它仅在接收到 HTTP 请求并呈现响应时在管道处理结束时触发。这意味着它不会为仅关闭浏览器的用户触发。此外,除了某些类型的会话状态之外,该事件永远不会触发 - 例如,它不适用于 State Server 或基于 SQL 的会话状态。最重要的是,您不能依赖它来维护明确的“已登录”标志。

相反,我会存储“收到的最后一页请求”时间戳。然后,您可以推断“已登录”标志的值;任何在过去 15 分钟内提交请求的用户仍处于登录状态。

【讨论】:

    猜你喜欢
    • 2011-05-26
    • 2021-08-30
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多