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

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

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

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

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

Спасибо

Ответы [ 15 ]

7 голосов
/ 17 февраля 2009

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

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

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

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

3 голосов
/ 21 сентября 2012

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

Пример:

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
3 голосов
/ 17 февраля 2009

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

2 голосов
/ 17 февраля 2009

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

Короче, №
Без написания какого-либо элемента управления ActiveX вы не могли бы написать код, который мог бы помешать пользователю открыть (отдельный экземпляр) IE / FF и т. Д., А один экземпляр мог бы обнаружить другой.

2 голосов
/ 17 февраля 2009

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

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

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, если он используется разработчиками, поэтому мы можем открыть его несколько раз

1 голос
/ 13 апреля 2017

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

Итак, вот хитрость: просто проверьте, имеет ли 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: пользователь может скопировать адрес внутренней страницы и вставить его на другую вкладку того же браузера ... вот почему я сказал "частично"

1 голос
/ 22 июня 2013

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

  $(window).blur(function(){

// code to stop functioning or close the page  

});
1 голос
/ 19 февраля 2009

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

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

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

1 голос
/ 17 февраля 2009

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

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

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

protected override object LoadPageStateFromPersistenceMedium()

protected override void SavePageStateToPersistenceMedium(object viewState)
0 голосов
/ 08 мая 2017

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

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

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

 if (!window.name || window.name != '@Session["WindowName"]') {
    //Log Off code
 }
...