Как отличить сеансы в браузере-вкладках? - PullRequest
129 голосов
/ 15 декабря 2008

В веб-приложении, реализованном на Java с использованием JSP и сервлетов; если я храню информацию в пользовательском сеансе, эта информация передается со всех вкладок одного и того же браузера. Как отличить сеансы в браузере-вкладках? В этом примере:

<%@page language="java"%>
<%
String user = request.getParameter("user");
user = (user == null ? (String)session.getAttribute("SESSIONS_USER") : user);
session.setAttribute("SESSIONS_USER",user);
%>
<html><head></head><body>
<%=user %>
<form method="post">
User:<input name="user" value="">
<input type="submit" value="send">
</form>
</body></html>

Скопируйте этот код на страницу jsp (testpage.jsp), разверните этот файл в существующем контексте веб-приложения на сервере (я использую Apache Tomcat), затем откройте браузер (FF, IE7 или Opera), используя правильный URL (localhost/context1/testpage.jsp), введите свое имя в поле ввода и отправьте форму. Затем откройте новую вкладку в том же браузере, и тогда вы сможете увидеть свое имя (получить из сеанса) на новой вкладке. Будьте осторожны с кешем браузера, иногда кажется, что этого не происходит, но он находится в кеше, обновите вторую вкладку.

Спасибо.

Ответы [ 21 ]

1 голос
/ 21 сентября 2009

Другой подход, который работает, заключается в создании уникального идентификатора окна и сохранении этого значения вместе с идентификатором сеанса в таблице базы данных. Идентификатор окна, который я часто использую, является целым числом (сейчас). Это значение создается, когда окно открывается и переназначается тому же окну, если оно обновляется, перезагружается или передается самому себе. Значения окна (входы) сохраняются в локальной таблице по ссылке. Когда значение требуется, оно получается из таблицы базы данных на основе ссылки идентификатора окна / идентификатора сеанса. Хотя этот подход требует локальной базы данных, он практически надежен. Мне было легко использовать таблицу базы данных, но я не вижу причин, по которым локальные массивы не будут работать так же хорошо.

1 голос
/ 15 декабря 2008

Вы можете использовать перезапись ссылок для добавления уникального идентификатора ко всем вашим URL-адресам, когда начинаете с одной страницы (например, index.html / jsp / что угодно). Браузер будет использовать одни и те же файлы cookie для всех ваших вкладок, поэтому все, что вы добавите в файлы cookie, будет , а не уникальным.

1 голос
/ 20 февраля 2015

Spring Session поддерживает несколько сеансов в одном браузере Посмотрите образцы и детали реализации http://docs.spring.io/spring-session/docs/current/reference/html5/guides/users.html

0 голосов
/ 08 июня 2015

Примечание: решение здесь должно быть сделано на этапе разработки приложения. Это будет сложно спроектировать позже.

Используйте скрытое поле для передачи идентификатора сеанса .

Чтобы это работало, каждая страница должна содержать форму:

<form method="post" action="/handler">

  <input type="hidden" name="sessionId" value="123456890123456890ABCDEF01" />
  <input type="hidden" name="action" value="" />

</form>

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

<input type="hidden" name="action" value="completeCheckout" />
<input type="hidden" name="data" value='{ "cardNumber" : "4111111111111111", ... ' />

Поскольку файлов cookie нет, каждая вкладка будет независимой и не будет знать о других сеансах в том же браузере.

Много преимуществ, особенно когда речь идет о безопасности:

  • Не зависит от JavaScript или HTML5.
  • По своей сути защищает от CSRF .
  • Не зависит от печенья, поэтому защищает от POODLE .
  • Не подвержен фиксации сессии .
  • Может предотвратить использование кнопки «назад», что желательно, если вы хотите, чтобы пользователи следовали по заданному пути через ваш сайт (это означает, что могут быть предотвращены логические ошибки, которые иногда могут быть атакованы запросами не по порядку).

Некоторые недостатки:

  • Функциональность кнопки Назад может быть желательна.
  • Не очень эффективно с кэшированием, так как каждое действие - это POST.

Дополнительная информация здесь .

0 голосов
/ 16 марта 2015

Я вижу много реализаций, в которых есть изменения на стороне клиента для манипулирования файлами cookie идентификатора сеанса. Но в общем случае куки с идентификатором сессии должны быть HttpOnly, чтобы java-скрипт не мог получить к ним доступ, иначе это может привести к перехвату сессии через XSS

0 голосов
/ 25 октября 2014

вам нужно будет сделать

1 - сохранить файл cookie для списка учетных записей

2 - опционально хранить куки по умолчанию

3 - хранить для каждой учетной записи с индексом, таким как acc1, acc2

4 - вставьте в URL что-то, обозначающее индекс счетов, и если нет, вы выберете индекс по умолчанию. как google mail domain.com/0/some-url >> 0 здесь представляют индекс аккаунта также вам может понадобиться знать, как использовать urlwrite

5 - при выборе файла cookie выберите его в соответствии с вашим URL-адресом, представляющим индекс учетной записи

Привет

0 голосов
/ 08 декабря 2015

Я решил это следующим образом:

  • Я присвоил окну имя, это имя совпадает с ресурсом соединения.
  • плюс 1, чтобы избавиться от сохраненных в cookie для подключения вложения.
  • Я создал функцию для захвата всех ответов xmloutput и назначения sid и rid для cookie в формате json. Я делаю это для каждого window.name.

здесь код:

var deferred = $q.defer(),
        self = this,
        onConnect = function(status){
          if (status === Strophe.Status.CONNECTING) {
            deferred.notify({status: 'connecting'});
          } else if (status === Strophe.Status.CONNFAIL) {
            self.connected = false;
            deferred.notify({status: 'fail'});
          } else if (status === Strophe.Status.DISCONNECTING) {
            deferred.notify({status: 'disconnecting'});
          } else if (status === Strophe.Status.DISCONNECTED) {
            self.connected = false;
            deferred.notify({status: 'disconnected'});
          } else if (status === Strophe.Status.CONNECTED) {
            self.connection.send($pres().tree());
            self.connected = true;
            deferred.resolve({status: 'connected'});
          } else if (status === Strophe.Status.ATTACHED) {
            deferred.resolve({status: 'attached'});
            self.connected = true;
          }
        },
        output = function(data){
          if (self.connected){
            var rid = $(data).attr('rid'),
                sid = $(data).attr('sid'),
                storage = {};

            if (localStorageService.cookie.get('day_bind')){
              storage = localStorageService.cookie.get('day_bind');
            }else{
              storage = {};
            }
            storage[$window.name] = sid + '-' + rid;
            localStorageService.cookie.set('day_bind', angular.toJson(storage));
          }
        };
    if ($window.name){
      var storage = localStorageService.cookie.get('day_bind'),
          value = storage[$window.name].split('-')
          sid = value[0],
          rid = value[1];
      self.connection = new Strophe.Connection(BoshService);
      self.connection.xmlOutput = output;
      self.connection.attach('bosh@' + BoshDomain + '/' + $window.name, sid, parseInt(rid, 10) + 1, onConnect);
    }else{
      $window.name = 'web_' + (new Date()).getTime();
      self.connection = new Strophe.Connection(BoshService);
      self.connection.xmlOutput = output;
      self.connection.connect('bosh@' + BoshDomain + '/' + $window.name, '123456', onConnect);
    }

Я надеюсь помочь вам

0 голосов
/ 22 ноября 2013
How to differ sessions in browser-tabs?

Самый простой способ различать сеансы на вкладках браузера - запретить настройку файлов cookie для вашего конкретного домена. Таким образом, вы можете иметь отдельные сессии из отдельных вкладок. Скажем, вы запрещаете куки с этого домена: www.xyz.com. Вы открываете Tab 1, авторизуетесь и начинаете просмотр. Затем вы открываете Tab 2, и вы можете войти в систему как тот же пользователь или другой; в любом случае у вас будет сеанс, отдельный от Tab 1. И так далее.

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

0 голосов
/ 06 октября 2013

Сохранение метки времени в window.sessionStorage, если она еще не установлена. Это даст уникальное значение для каждой вкладки (даже если URL совпадают)

http://www.javascriptkit.com/javatutors/domstorage.shtml

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage

Надеюсь, это поможет.

0 голосов
/ 19 апреля 2016

Если из-за того, что на каждой вкладке будет выполняться отдельный поток в вашем приложении, а смешивание обоих потоков вызывает проблемы, тогда лучше «регионализировать» объекты сеанса, чтобы каждый поток использовал свою область сеанса

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

...