Session_End в Global.asax.cs не запускается - PullRequest
0 голосов
/ 01 марта 2019

У меня есть веб-приложение Asp.net, где я использую FormsAuthentication для входа в систему пользователя.

Я хочу запретить несколько входов в систему для одного и того же пользователя одновременно.Для этого я установил тайм-аут FormsAuthentication на 15 минут, а Session.timeout на 15 минут.

Когда пользователь закрывает браузер без выхода из системы или если пользователь неактивен в течение 15 минут, он не запускаетСобытие Session_End () в файле global.asax.cs.Я хочу обновить поле базы данных в событии 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, этот пользователь не сможет снова войти в систему.

Пожалуйста, предложите.

1 Ответ

0 голосов
/ 02 марта 2019

Session_End на самом деле не настолько полезен или надежен.С одной стороны, он запускается только в конце конвейерной обработки, когда получен HTTP-запрос и получен ответ.Это означает, что он НЕ срабатывает для пользователя, который просто закрыл свой браузер.Кроме того, событие никогда не сработает, за исключением определенных типов состояния сеанса - оно не будет работать, например, с State Server или состоянием сеанса на основе SQL.Суть в том, что вы не можете полагаться на него, чтобы поддерживать однозначный флаг «Вход в систему».

Вместо этого я бы сохранил отметку времени «запрос последней страницы получен».Затем вы можете вывести значение флага «зарегистрирован»;любой пользователь, который отправил запрос за последние 15 минут, все еще входит в систему.

...