#javascript #jquery #backbone.js
#javascript #jquery #backbone.js
Вопрос:
Я пишу веб-сайт, который по сути является клиентским веб-приложением, т. Е. Все на странице заполняется скриптами с данными из ajax API. Пользователи также будут входить в систему и выходить из нее, используя набор API.
Мой вопрос заключается в том, как справиться со следующим (но не совсем экстремальным) вариантом использования:
- Пользователь открывает вкладку браузера A, переходит на веб-сайт и регистрируется как пользователь # 1.
- Пользователь открывает вкладку браузера B и также переходит на веб-сайт. Поскольку существует API get_session, скрипт восстанавливает сеанс на вкладке B.
- Пользователь вышел из вкладки B, оставив вкладку A открытой.
- Пользователь на какое-то время забывает о вкладке A, возвращается и взаимодействует с вкладкой A.
- Скрипты на вкладке A пытаются получить новые данные от имени пользователя # 1, но сталкиваются с ошибкой.
В идеале, на шаге 3 должен быть какой-то способ, чтобы вкладка A также выходила из системы, когда пользователь нажимает «Выход из системы» на вкладке B.
На шаге 5 можно выйти из вкладки A (это делает GMail), но я думаю, что должен быть лучший способ. Даже проверка на шаге 5 была бы нетривиальной, потому что для такого дизайна каждый API должен точно знать, данные какого пользователя запрашивает скрипт, иначе приведенный ниже вариант использования сгенерирует неверный вывод.
(1-3) то же, что и выше.
- Пользователь открывает вкладку браузера A, переходит на веб-сайт и регистрируется как пользователь # 1.
- Пользователь открывает вкладку браузера B и также переходит на веб-сайт. Поскольку существует API get_session, скрипт восстанавливает сеанс на вкладке B.
- Пользователь вышел из вкладки B, оставив вкладку A открытой.
- Пользователь снова входит в систему с вкладки B, но на этот раз как пользователь # 2.
- Пользователь возвращается на вкладку A и становится интерактивным. Думая, что пользователь является пользователем № 1, скрипт на вкладке A запрашивает данные из API.
- API возвращает данные, принадлежащие пользователю № 2. Boom.
Существует ли обычная практика для предотвращения подобных проблем? Спасибо.
Тим
Комментарии:
1. Не совсем уверен, насколько это эффективно, или это обычное явление, но у вас мог бы быть Javascript, который проверяет каждые x секунд, зарегистрирован ли пользователь # 1. Если нет (сеанс или файл cookie не существует), выйдите из системы пользователя.
2. @xbonez Я так и думал, но серверный инженер, отвечающий за get_session, убьет меня, если я это сделаю (учитывая тот факт, что это, вероятно, убило бы сервер …)
3. Определенный объем обмена сообщениями между окнами / документами возможен с помощью postMessage API. Текущую поддержку смотрите здесь: caniuse.com/#search=cross-do
4. Насколько я могу судить, @timdream , это единственный способ сделать это. Если вы не используете websockets, что на данный момент не является стандартом; вам придется проверять этот сеанс с помощью скрипта, который запускается каждые x секунд.
5. Распространенная проблема при «многократном входе в систему в одном браузере» … вообще говоря, это возможно, если вкладки A и B могут предоставлять разные токены аутентификации для подтверждения своей личности, и приложение должно иметь возможность восстановить идентификацию, если на вкладке нет выхода из системы. Однако это может быть своего рода проблемой безопасности, поскольку процесс выхода из системы потребует выхода из всех вкладок! (Или ваш серверный инженер убьет вас)
Ответ №1:
Ответ ajax должен указывать в качестве условия ошибки, что пользователь вышел из системы; на стороне клиента обнаружьте эту ошибку и выполните соответствующее действие. Очевидно, что это работает только при наличии ajax-ответа, поэтому вы можете захотеть реализовать какой-то механизм «сердцебиения», то есть клиент отправляет ajax-сообщение, подобное ping, на сервер каждые несколько секунд. При выходе из системы сервер ответит на сердцебиение ошибкой «пользователь вышел из системы», и клиент может перейти в режим «не авторизован».
Комментарии:
1. Спасибо. Это было бы похоже на комментарий # 1. Я подумаю об этом.
2. Основным недостатком этого подхода является то, что сеанс никогда не прерывается. Предположим, что пользователь долгое время простаивает, тогда в идеале сеанс должен автоматически аннулироваться по истечении определенного периода ожидания сеанса, но при таком подходе, поскольку мы каждые несколько секунд пингуем сервер, чтобы проверить его статус, тайм-аут никогда не будет
3. @anu: верно. Если вам нужно время ожидания сеанса, даже если браузер все еще открыт, вы, конечно, можете реализовать свой собственный тайм-аут, который не зависит от сообщений о сердцебиении, а скорее только от «реальных» действий.
Ответ №2:
Я не думаю, что существует, потому что такая связь между страницами (вкладками) была бы значительным недостатком безопасности. Однако вы могли бы добиться того же эффекта, если бы каждая страница (вкладка) опрашивала сервер, чтобы узнать, действителен ли сеанс по-прежнему. Или используйте один из методов обработки событий, таких как длительный опрос или потоковая передача в iframe.