none
Завершение работы пользователя в системе после закрытия браузера. RRS feed

Ответы

  • CheckBox isKeepMeLoggedIn = (CheckBox)LoginUser.FindControl("RememberMe");
    FormsAuthentication.SetAuthCookie(username, isKeepMeLoggedIn.Checked);

    Я косячник - только голову Вам морочил, всего две строчки кода и всё рабоат 
    • Помечено в качестве ответа ansi_str 13 июля 2012 г. 10:54
    • Изменено ansi_str 13 июля 2012 г. 10:54
    13 июля 2012 г. 10:53

Все ответы

  • Вот способ первый, пришедший пока в голову, когда то я его даже использовал. Страница с которой должен быть выход, если хотите для всех пишите скрипт в мастер страницу.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm.aspx.cs" Inherits="WebSessionEnd.WebForm" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body onunload="bodyUnload();" onclick="bodyClicked();">
        <form id="form" runat="server">
        <div>
    
        </div>
        </form>
    </body>
    <script type="text/javascript">
      var bodyClicked = false;
      function bodyClicked() {
        bodyClicked = true;
      }
      function CheckBrowser() {
        if (bodyClicked == false) {
          //Браузер уже закрыт  
        } else {
          bodyClicked = false;
        }
      }
      function bodyUnload() {
        if (bodyClicked == false)  
        {
          var request = SendRequest();
          request.open("GET", "/SignOut.aspx", true);
          request.send();
        }
      }
      function SendRequest() {
        var xhr = null;
        if (window.XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        }
        else {
          xhr = new ActiveXObject("Msxml2.XMLHTTP");
          if (!xhr) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
          }
        }
        return xhr;
      } 
    </script>
    </html>
    

    Код станицы для выхода

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SignOut.aspx.cs" Inherits="WebSessionEnd.SignOut" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form" runat="server">
        <div>
        </div>
        </form>
    </body>
    </html>

    ничего особенного, её функция только одна (в MVC можно было обойтись проще, выделить отдельный метод действия, чтобы не создавать целую страницу для этого, но это WebForms)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WebSessionEnd
    {
      public partial class SignOut : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          Session.Abandon();
        }
      }
    }

    Если хотите протестить в браузере открываете две вкладки во время отладки, при закрытии одной (браузер не должен закрываться, иначе отладка завершится автоматом) если установлена точка прерывания в Session.Abandon(), то произойдёт останов и можно увидеть, что всё работает.

    13 июля 2012 г. 6:18
    Модератор
  • Спасибо, сделал

    Всё так, как Вы предложили, но до метода, закрывающего сессию
    Session.Abandon();
    При отладке запрос не доходит.

    13 июля 2012 г. 6:41
  • А что именно происходит?
    13 июля 2012 г. 6:43
    Модератор
  • ничего особенного, её функция только одна (в MVC можно было обойтись проще, выделить отдельный метод действия, чтобы не создавать целую страницу для этого, но это WebForms)

    В WebForms тоже нет нужды создавать отдельную страницу. 

    1. В MasterPage-е можно разместить контрол, реализующий интерфейс ICallbackEventHandler. При закрытии страницы вызывать Callback,

    в обработчике Callback-а закрывать сессию. 

    2. В базовом классе, от которого наследуются все страницы (если конечно такой есть) разместить статический метод, какой нибудь такой:

    [WebMethod(EnableSession = true)]
    public static string CloseSession()
    {
    //тут закрывать сессию... 
    }

    этот метод вызывать ajax-ом с мастер page-а при закрытии страницы. 

    -------------

    Это так на вскидку, может что-то не учитываю... 


    • Изменено A.G.Sedov 13 июля 2012 г. 6:48
    13 июля 2012 г. 6:47
  • В том то и дело - ничего

    Я запускаю проект в режиме отладки.
    Ставлю точку, чтобы удостовериться - запрос к странице пришёл.
    Но он не приходит.

    А продебажить скрипт при закрытии браузера невозможно...
    13 июля 2012 г. 6:49
  • ничего особенного, её функция только одна (в MVC можно было обойтись проще, выделить отдельный метод действия, чтобы не создавать целую страницу для этого, но это WebForms)

    В WebForms тоже нет нужды создавать отдельную страницу. 

    1. В MasterPage-е можно разместить контрол, реализующий интерфейс ICallbackEventHandler. При закрытии страницы вызывать Callback,

    в обработчике Callback-а закрывать сессию. 

    2. В базовом классе, от которого наследуются все страницы (если конечно такой есть) разместить статический метод, какой нибудь такой:

    [WebMethod(EnableSession = true)]
    public static string CloseSession()
    {
    //тут закрывать сессию... 
    }

    этот метод вызывать ajax-ом с мастер page-а при закрытии страницы. 

    -------------

    Это так на вскидку, может что-то не учитываю... 


    Это же для закрытия одной вкладки(страницы), а если у пользователя их 5 открыто?
    13 июля 2012 г. 6:51
  • Вот Вам ссылка на проект, там всё протестировано и работает. "Это же для закрытия одной вкладки(страницы), а если у пользователя их 5 открыто?" - это веб, тут уже ничего не поделать.
    13 июля 2012 г. 6:55
    Модератор
  • Это же для закрытия одной вкладки(страницы), а если у пользователя их 5 открыто?

     Что значит для одной вкладки(страницы)? Вам же сессию надо закрыть - в предложенных случаях сессия закроется при закрытии любой страницы. Или вам нужно чтобы сессия закрылась только тогда, когда закрыты все страницы с вашего веб-приложения?
    • Изменено A.G.Sedov 13 июля 2012 г. 7:09
    13 июля 2012 г. 7:08
  • "В WebForms тоже нет нужды создавать отдельную страницу. " - по вашему это более легковесный вариант. Нет, не думаю. Скорее наоборот. Это  веб-формы, и от жизненого цикла обработки страницы не уйти. Основная идея использования ICallbackEventHandler иметь возможность частично обновлять сраницу, а возможность эта даётся очень высоким уровнем абстракции. А для этого примера она нам вообще не нужна, ведь мы ничего на клиент обратно не отправляем. Это своего рода серверная заглушка, а реализовать ICallbackEventHandler для подобного уже излишне.
    13 июля 2012 г. 7:14
    Модератор
  • Нет, я хочет узнать, задача именно про одну вкладку
    У пользователя открыто 10 вкладок.
    Он одну закрывает, остальные 9 остаются открытыми.

    Соответственно нам  не нужно закрывать сессию.
    13 июля 2012 г. 7:27
  • Спасибо, за Ваш проект работает
    При вызове Session.Abandon не закрывается сессия и пользователь всё равно остаётся в системе

    Если мы будем переходить с одно ссылки на другую в странице, мы же постоянно будем вызывать запросы к SignOut.aspx


    13 июля 2012 г. 7:38
  • Если вкладки в одном браузере открыты, то можно кое-как дотянуться до них из JavaScript, а если в разных браузерах, то тут ничего не поделать уже. Чтобы не заниматься подобного рода шаманством как раз и был придуман таймаут сессии. Это веб, и с некоторыми вещами приходится мириться, если хотите короткую сессию, то ставьте таймаут коротким. "При вызове Session.Abandon не закрывается сессия и пользователь всё равно остаётся в системе" - сессия с авторизаций ничего общего не имеет.

    "Если мы будем переходить с одно ссылки на другую в странице, мы же постоянно будем вызывать запросы к SignOut.aspx" - да, об этом не подумал, посмотрю.

    13 июля 2012 г. 7:46
    Модератор
  • Можно сделать так.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm.aspx.cs" Inherits="WebSessionEnd.WebForm" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
      <title></title>
    </head>
    <body>
      <form id="form" runat="server">
      <div>
        <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Redirect.aspx">HyperLink</asp:HyperLink>
      </div>
      </form>
    </body>
    <script type="text/javascript">
      window.onbeforeunload = function () { ClearSession(); }
      function ClearSession() {
          var request = SendRequest();
          request.open("GET", "/SignOut.aspx", true);
          request.send();
      }
      function SendRequest() {
        var xhr = null;
        if (window.XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        }
        else {
          xhr = new ActiveXObject("Msxml2.XMLHTTP");
          if (!xhr) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
          }
        }
        return xhr;
      } 
    </script>
    </html>
    

    В предыдущем примере я перестарался. Но работать это будет только, как и предыдущий пример если не делать редиректов в принципе. Т.е. зарузить страницу, а потом Ajax - ом делать всё, но это уже шаманство. А вообще я предлагаю забыть про эту идею вообще, так как она почти нереализуема. Назначте короткий таймаут сессии и дело с концом.

    P.S. Это Веб, и надо с этим мириться.

    13 июля 2012 г. 8:47
    Модератор
  • Может быть в сессии или в куках хранить число открытых вкладок (соотвественно инкрементировать и декрементировать их при открытии/закрытии новой). При достижении счетчика нуля убивать сессию, как в одном из вариантов выше.


    Для связи [mail]

    13 июля 2012 г. 9:41
    Модератор
  • Я не корректно, не правильно вопрос поставил

    Задача стоит такая
    Пользователь вводит пароль и логин и заходит в систему.
    Ставит или нет галочку keep me log in.

    При закрытии браузера: если галочка стоит, то если через какое о время пользователь снова зайдёт на сайт, то ему не нудно будет снова авторизовываться.
    если галочка не стоит, то если через какое то время пользователь снова зайдёт на сайт, то ему не нужно будет авторизовываться.
    13 июля 2012 г. 9:47
  • Похоже Вы путаете сессию и аутентификацию. Если используете элемент управления Login, так там этот сценарий уже за Вас реализован. Если галочка стоит, без разницы, сколько раз пользователь закрывает и открывает браузер. А если не стоит, то по истечению срока действия куки(который вы задаёте) пользователь автоматом выйдет из системы. А что касается закрытия браузера и выхода из системы (сброса куки), то от этого суть поставленного вопроса не меняется, всё тоже самое.
    13 июля 2012 г. 10:13
    Модератор
  • Да, вы правы - путаю

    Но галочка у элемента управления Login  не рабоат
    13 июля 2012 г. 10:16
  • Надо было именно с этого и начинать. Возможно в браузере утановлена чистка куки после выхода, или срок истечения куков слишком маленький.
    13 июля 2012 г. 10:34
    Модератор
  • CheckBox isKeepMeLoggedIn = (CheckBox)LoginUser.FindControl("RememberMe");
    FormsAuthentication.SetAuthCookie(username, isKeepMeLoggedIn.Checked);

    Я косячник - только голову Вам морочил, всего две строчки кода и всё рабоат 
    • Помечено в качестве ответа ansi_str 13 июля 2012 г. 10:54
    • Изменено ansi_str 13 июля 2012 г. 10:54
    13 июля 2012 г. 10:53
  • Да, бывает. Но заглавие темы : "Завершение работы пользователя в системе после закрытия браузера." всё равно очень полезное.
    13 июля 2012 г. 10:59
    Модератор