Как запретить пользователю иметь несколько экземпляров одного и того же веб-приложения

Мне интересно, можно ли определить, есть ли у пользователя веб-браузер, открытый для веб-приложения, над которым я работаю. Похоже, что они могут открыть несколько экземпляров одного и того же веб-приложения и щелкнуть по кнопкам, чтобы прочитать информацию, которую они использовали прежде, чтобы войти в экран ввода, над которым они в данный момент работают.

Что происходит, однако, это то, что кажется, что он испортил переменные сеанса, и тогда пользователь обновит свою предыдущую работу своей новой работой. Или они удалят свои предыдущие работы все вместе или кто знает ...

ИЗМЕНИТЬ Я уже видел это в веб-приложениях для онлайн-банкинга. Если вы уже вошли в систему, новое окно сообщит вам, что приложение уже открыто. В моем случае пользователю не нужно входить в систему.

Есть ли простой способ определить, есть ли у них окно браузера, открытое для веб-приложения, и если это так, просто закройте браузер или откройте другую страницу, чтобы сообщить им, что за один раз можно открыть только 1?

Спасибо

12 голосов | спросил Eppz 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:01:51 +0300000000pmTue, 17 Feb 2009 20:01:51 +030009 2009, 20:01:51

14 ответов


0

Во-первых, нет, во-вторых, не стоит пытаться.

Стратегия всплывающего окна не будет работать (и будет раздражать пользователей). Мой браузер настроен на «Открывать окна как вкладки», и Я выбираю, нужно ли разделить одно окно на другое. Или в некоторых случаях, запускать ли другой браузер - не просто другой экземпляр того же самого - для отображения другой страницы на том же сайте.

И наоборот, идентификатор мини-сеанса не будет выполнен, поскольку сервер не может отследить, был ли запрос от того же пользователя , что и существующий сеанс. Несколько человек могут использовать одну и ту же машину, даже с одним и тем же именем пользователя; или один человек может иметь несколько отдельных сеансов входа в систему на одной или нескольких машинах.

Просто отсортируйте ваш протокол и переменные 'Session' и убедитесь, что последние зафиксированные изменения являются теми, которые сохраняются.

ответил 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:53:55 +0300000000pmTue, 17 Feb 2009 20:53:55 +030009 2009, 20:53:55
0

Вы можете назначить идентификатор «мини-сеанса» каждому экземпляру формы ввода, а затем использовать AJAX для проверки связи с сервером с этим идентификатором. Если пользователь пытается запросить ту же форму при наличии активного идентификатора, он должен отобразить сообщение об ошибке. Если сервер не слышит пинг в течение определенного времени, истекает мини-сеанс. (Это в основном очень простая стратегия блокировки)

ответил Justin Voss 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:32:53 +0300000000pmTue, 17 Feb 2009 20:32:53 +030009 2009, 20:32:53
0

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

Пример:

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Try
        If Not IsPostBack Then
            'SET LOCAL VARIABLE AND SESSION VARIABLE TO A UNIQUE VALUE
            'IF THE USER HAS CHANGED TABS THIS WILL CHANGE THE VALUE OF THE SESSION VARIABLE
            Me.HiddenInput.value = New Guid().ToString
            Me.Session.Add("PageGuid", Me.HiddenInput.value)

        Else 
            'ON POSTBACK, CHECK TO SEE IF THE USER HAS OPENED A NEW TAB
            'BY COMPARING THE VALUE OF THE LOCAL VALUE TO THE VALUE OF THE SESSION VARIABLE

            If me.HiddenInput.value <> CType(Session("PageGuid"), String) Then

                'THE VALUES DO NOT MATCH, MEANING THE USER OPENED A NEW TAB.
                'REDIRECT THE USER SOMEWHERE HARMLESS

                Response.Redirect("~/Home.aspx")

            Else

                'THE VALUES MATCH, MEANING THE USER HAS NOT OPENED A NEW TAB
                'PERFORM NORMAL POSTBACK ACTIONS

                ...

            End If
        End If
    Catch ex As Exception
        Me.Session.Add("ErrorMessage", BusinessLogic.GetErrorMessage(ex))
        Me.Response.Redirect("~/ErrorPage.aspx", False)
    End Try
End Sub
ответил user1484019 21 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 21 Sep 2012 20:57:48 +0400 2012, 20:57:48
0

Я использую хитрость открытия нового окна с определенным идентификатором и всегда проверяю, что любая страница будет открываться, всегда использую это окно.

С другой стороны, у них должен быть отключен блокировщик всплывающих окон для вашего сайта. Это хорошо работает для сайтов компании.

if (useOwnWindow && window.name != 'YourAPP'){
    var w = window.open(document.location, 'YourAPP', 'toolbar=no,status=yes,resizable=yes,scrollbars=yes');
    if (w==null){
        alert("Please turn off your pop-up blocker");
    }else{
        window.open('','_parent','');
        self.opener="";
        self.close();
    }
 }

Обратите внимание на флаг useOwnWindow, если он используется разработчиками, чтобы мы могли открыть его несколько раз

ответил Glennular 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:26:21 +0300000000pmTue, 17 Feb 2009 20:26:21 +030009 2009, 20:26:21
0

Я бы посоветовал вам хэшировать ViewState для страницы и сохранять его в переменной сеанса, прежде чем он будет возвращен в качестве ответа.

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

Два метода класса Page, которые вы хотите переопределить:

protected override object LoadPageStateFromPersistenceMedium()

protected override void SavePageStateToPersistenceMedium(object viewState)
ответил Dave Anderson 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:51:16 +0300000000pmTue, 17 Feb 2009 20:51:16 +030009 2009, 20:51:16
0

Мы реализовали решение этой проблемы на slicethepie.com. Пользователям (или «разведчикам») разрешено открывать только одно окно браузера за раз, чтобы они могли слушать музыку, за которую им платят за рецензирование.

Когда скаут запрашивает первый трек для обзора в ходе его скаутского сеанса, мы устанавливаем новый Guid для его учетной записи и возвращаем этот «ключ» вместе с деталями трека, который они дают для проверки. Бывает, что получателем этого ключа является флэш-фильм, но это не обязательно. Ключ повторно отправляется вместе с обзором разведчика, и мы проверяем, соответствует ли он сохраненному ключу. Если это не так, они начали новый сеанс разведки в новом окне.

Я не имею в виду, что этот метод надежен, но его можно легко адаптировать к вашим потребностям.

ответил Paul Suart 19 FebruaryEurope/MoscowbThu, 19 Feb 2009 18:02:58 +0300000000pmThu, 19 Feb 2009 18:02:58 +030009 2009, 18:02:58
0

Как уже упоминали другие, вы не можете помешать пользователю начать новый сеанс, не прибегая к ActiveX или другим мерзостям. Основная проблема в том, что у вас нет возможности узнать, закрыл ли пользователь старое окно браузера или оставил его открытым.

Однако вы можете сделать недействительным предыдущий сеанс, как только пользователь войдет в новый (немного похоже на поведение клиентов мгновенных сообщений).

При каждом входе в систему назначайте новый GUID пользователю в вашей базе данных. Также сохраните этот GUID в кеше сеанса (нет необходимости отправлять его туда и обратно на страницы, которые в любом случае не будут работать для запросов GET). При каждом запросе страницы сравнивайте GUID, назначенный пользователю в базе данных, с GUID в кэше сеанса. Если они не совпадают, верните ответ «Вы вошли откуда-то еще».

Обновление Я был слишком быстр при срабатывании триггера. Это не мешает сценарию, когда пользователь открывает несколько вкладок /окон в одном и том же процессе браузера. Таким образом, вам придется объединить это решение с предложением Дейва Андерсона для хранения хэша ViewState (или просто GUID), чтобы разрешить обратную запись только последней обслуживаемой странице в сеансе.

Обновление безопасности Кроме того, вы можете полагаться на эту платформу только для удобства пользователя, поскольку она небезопасна. Любой наполовину приличный хакер сможет обойти эти меры.

ответил PeterR 31 MarpmTue, 31 Mar 2009 21:49:38 +04002009-03-31T21:49:38+04:0009 2009, 21:49:38
0

Вы можете остановить функциональность страницы, когда пользователь открыл другую вкладку или другое окно или даже другой браузер

  $(window).blur(function(){

// code to stop functioning or close the page  

});
ответил 22 J0000006Europe/Moscow 2013, 17:02:11
0

Я частично решил проблему таким образом. Мое приложение запрашивает у пользователей аутентификацию ... поэтому они вводят имя пользователя и пароль. Когда они нажимают кнопку отправки, я сохраняю обе данные в переменной сеанса, то есть я сохраняю имя пользователя в сеансе («имя_пользователя»).

Итак, вот хитрость: просто проверьте, имеет ли значение Session ("LoginName") ДО ТОГО, как пользователь вводит его, в событии загрузки страницы на странице входа. Если это так, это несколько сеансов, и вы можете остановить пользователя или что-то еще.

Что-то вроде (я использую VB):

    If Not Page.IsPostBack Then
       Try
          If Session("LoginName") <> "" Then
             Response.Redirect("www.mysite.com")
             Exit Sub
          End If
       Catch ex As Exception
          ' Do something
       End Try

PRO: очень просто

CON: пользователь может скопировать адрес внутренней страницы и вставить его на другую вкладку того же браузера ... вот почему я сказал "частично"

ответил Riccardo Esercitato 13 PMpThu, 13 Apr 2017 12:13:56 +030013Thursday 2017, 12:13:56
0

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

ответил Jason 17 FebruaryEurope/MoscowbTue, 17 Feb 2009 20:09:58 +0300000000pmTue, 17 Feb 2009 20:09:58 +030009 2009, 20:09:58
0

Если кто-то скопирует URL-адрес веб-сайта и вставит его в новое окно или вкладку, история браузера для этого окна /вкладки будет пустой ... так что вы можете использовать javascript и просматривать историю ..

if (history.length == 1) {  //0 for IE, 1 for Firefox
    // This is a new window or a new tab.
}

Теперь вы можете предложить пользователю закрыть вкладку или отключить эту страницу (например, сделав все элементы disabled).

ответил Rosdi Kasim 10 Maypm12 2012, 20:03:39
0

У меня была такая же проблема, и я решил ее с помощью веб-сокетов (я использую pusher с php). Когда пользователь попадает на страницу, я устанавливаю переменную:

var firstTimeHere = true;

Затем я создал функцию веб-сокета в javascript, в которой идентификатор пользователя является частью имени функции, например:

var pingUser123 = function(){...}; 

Затем я использую ajax для запроса к серверу, на котором запущена сторона php веб-сокета:

$this->trigger("pingUser123");

Websocket запускает все экземпляры javascript этой функции в любом количестве окон на любом количестве браузеров и машин. Оттуда я могу видеть, был ли это первый раз, когда этот браузер был проверен. если это так, то это единственный случай, если нет, то второй.

var pingUser123 = function(){
    if(firstTimeHere){
       firstTimeHere = false;
    }else{
        app.stop();
        alert("Only one window at a time please.");
    }
};
ответил okwme 20 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 20 Sep 2016 16:53:39 +0300 2016, 16:53:39
0
 <script type="text/javascript">
        window.onload = function(){
        if (document.cookie.indexOf("_instance=true") === -1) {
        document.cookie = "_instance=true";
        // Set the onunload function
        window.onunload = function(){
            document.cookie ="_instance=true;expires=Thu, 01-Jan-1970 00:00:01 GMT";
        };
        // Load the application
        }
        else {
             alert(" Security Alerts.You Are Opening Multiple Window. This window will now close.");
             var win = window.open("about:blank", "_self"); win.close();
        // Notify the user
        }
        };
    </script>
ответил Sankar Smith 29 22016vEurope/Moscow11bEurope/MoscowTue, 29 Nov 2016 08:01:57 +0300 2016, 08:01:57
0

Вы можете сделать это с помощью window.name. В java-скрипте window.name имеет пустое значение на каждой новой вкладке. Установите значение window.name на странице входа и сохраните в сеансе.

window.name = Math.random() + "_YourApplication"

Теперь проверьте это имя окна на главной странице /странице макета. Выйдите из системы, если пользователь содержит несколько вкладок.

 if (!window.name || window.name != '@Session["WindowName"]') {
    //Log Off code
 }
ответил Saurabh Tripathi 8 Maypm17 2017, 14:55:40

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132