laravel и multi-сеансы из одного браузера

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

Мы используем Laravel 5. Есть ли способ обойти это?

История сеанса Laravel

сессии

Пропустите этот раздел для быстрого простого решения

В Laravel сеансовые файлы cookie создаются с помощью класса Illuminate\Session\SessionManager , а именно с помощью метода buildSession :

SessionManager :: buildSession

 protected function buildSession($handler) { if ($this->app['config']['session.encrypt']) { return new EncryptedStore( $this->app['config']['session.cookie'], $handler, $this->app['encrypter'] ); } else { return new Store($this->app['config']['session.cookie'], $handler); } } 

В этом методе мы можем четко видеть, что имя сеанса происходит из нашего config\session.php , в частности, в этой строке:

session.php

 'cookie' => 'laravel_session', # ~~ ln 121 at time of writing 

Хорошо, но это не очень помогает, изменяя это, меняет его везде, как отмечено комментарием, продолжая его в конфиге.

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

И даже если бы мы могли передать ему какое-то динамическое значение, что-то вроде:

 'cookie' => 'laravel_session' . user()->id, 

Это создает парадоксальный, окончательный конец времени, последствия взрыва во вселенной, потому что вы запрашиваете id от user которому осуществляется доступ через session просматриваемый именем cookie laravel_session .. (mindblown)

Оставим SessionManager и его конфигурацию session.php . Мы можем видеть сверху, что независимо от того, как мы подходим к этому, вся наша информация о сеансе будет подпадать под этот единственный ключ laravel_session .

охрана

Возможно, у гвардии будет дополнительная информация.

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

Метод, которым нужно смотреть, – Guard::user() .

Одна из первых вещей, которые Guard::user() делает после некоторого начального кэша и проверяется, является проверкой сеанса.

Guard :: пользователя ()

 $id = $this->session->get($this->getName()); 

Итак, здесь Laravel getName() значения сеанса, которые соответствуют результату getName() – awesome – все, что нам нужно сделать, это mod getName() чтобы вернуть значение, возьмем getName() при этом метод:

Guard :: GetName ()

 public function getName() { return 'login_'.md5(get_class($this)); } 

Это довольно прямолинейно. $this относится к классу Guard, поэтому md5 будет всегда всегда быть одинаковым (если кто-то знает, почему «за» md5'ин имя класса будет одинаковым каждый раз, оставьте комментарий).

Есть несколько мест, где это должно быть обновлено, например getRecallerName .

Итак, отсюда вы можете расширить основной класс Guard и сплайсинг в методах getName и getRecallerName.

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

«Боже, это похоже на большую работу»

«Это, конечно, Билли, он уверен,

https://www.youtube.com/watch?v=dTxQ9yhGnAg

См. Следующую часть

Быстрый ответ «Мне нужен ответ»

Ollie Read уже создал решение, которое можно найти здесь:

https://github.com/ollieread/multiauth

Я рекомендую вам взглянуть, особенно пользовательский класс Guard который расширяет core Guard с помощью пользовательских методов getName .

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

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

1) Используйте разные браузеры для разных пользователей. Различные браузеры не разделяют куки между ними. Если ваша цель – просто протестировать ваш сайт с несколькими пользователями, это так. Вы также можете использовать режим Incognito / Private для входа отдельного пользователя, так как этот режим также не поддерживает файлы cookie.

2) Не используйте файлы cookie сеансов для хранения информации о пользователе. Это не стартер на большинстве веб-сайтов, но если это внутренний сайт или строго контролируемая среда, вы можете пройти идентификацию пользователя через URL-адрес, данные POST или какой-либо другой скрытый идентификатор в запросе.

3) Храните данные в файле cookie сеанса для всех зарегистрированных пользователей. В зависимости от веб-структуры может быть возможно создать карту user -> cookieData и найти правильный, основанный на том, какой пользователь выполняет запрос. Это продвинутая техника, и я действительно не знаю, раскрывает ли Laravel этот уровень контроля.

tl; dr: Yagni

Рассмотрим человека (http-клиент в вашем случае) с двумя идентификаторами: Dr Jekyll и Mr Hyde .
Он посещает своего нового друга сэра RM1970 (http-сервер в вашем случае): « Как вы RM1970 , RM1970 ! ».
Вот проблема. Бедный RM1970 должен приветствовать монстра, и есть несколько вариантов:

  • погрузитесь в эту кроличью нору: « Как вы делаете и Dr Jekyll и Mr Hyde ! », что невероятно усложняет дальнейший разговор (например, ваш ACl должен будет работать со списком идентичностей и принимать решения о приоритетах, если они конфликт в реальном времени)
  • самостоятельно принять решение: « Как вы делаете Dr Jekyll ! » и молитесь, чтобы вы сделали правильный выбор (случайно выберите личность пользователя и принесите своим пользователям удовольствие от непредсказуемых ответов)
  • лукаво и отнести эту ответственность к нему: « Простите меня? Кто вы? Назовите себя! » (требуется отдельное удостоверение личности за запрос)

Позже это то, как это работает. Браузер обеспечивает последнюю подтвержденную идентификацию.
Вас попросили изменить это, но вы действительно этого хотите? Держите линию и не принимайте эту ответственность.
Если вы не собираетесь использовать первые два тупиковых варианта, вам нужно будет спросить пользователя, от какого имени он отправляет запрос. Самый лучший вариант здесь – сделать свой внешний вид stateful, поддерживать список открытых сеансов и предоставить пользовательский интерфейс для пользователя. Это почти третий вариант Райана Бемроуза, но сохраните эти данные на стороне клиента и отправьте только выбранную. Никаких изменений в брандмауэре laravel не требуется.

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

Некоторые браузеры поддерживают несколько профилей ( пример ), что может быть приемлемой альтернативой. В принципе это то же самое, что и первый вариант Райана Бемроуза, но не требует установки нескольких браузеров и может использовать постоянные файлы cookie, также известные как «Remember-me».

Самый простой из них – это только идентификатор сеанса, основанный на URL, который может быть проблемой безопасности в зависимости от того, как разрабатывается ваше приложение, особенно при совместном использовании URL-адресов с сеансами без истечения срока действия.

Поскольку L5 больше не поддерживает собственные сеансы php, вам придется использовать настраиваемый поставщик, как показано ниже:

Это будет использовать sessionID в url для laravel V5:

https://github.com/iMi-digital/laravel-transsid

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

Библиотека выше блокирует сеанс для IP и User Agent, поэтому совместное использование ссылок не приведет к случайному утечке сеанса.

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

Я знаю, что это не ответ на ваш вопрос, но это может быть то, что вы ищете.

Различные видения, сосуществующие между одновременными входами в пользователей, не могут быть реализованы только в cookie сеанса, потому что cookie хранится браузером. Таким образом, регистрируемое входное имя пользователя должно храниться сервером. Как известно, после вызова session_start создается SessionID, а затем создается временный файл во временном каталоге сервера.

У разного пользователя разные SessionID и после вызова session_destory все восстановленные идентификаторы SessionID, хранящиеся в Server и Cookies. Вы можете переписать это поведение, выполнив SessionHandlerInterface. Из-за этого многие веб-среды поддерживают это, Laravel не исключение. Вот документ: custom-session-drivers

Я не знаю, как усложнить его кодирование в laravel, но это может быть одно решение:

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

 <?php if(isset($_GET['id']) && !empty($_GET['id'])) session_name($_GET['id']); session_start(); if(isset($_GET['user'])) { $_SESSION['user'] = $_GET['user']; } if(!empty($_SESSION['user'])) echo "Hello ".$_SESSION['user']; 

Multi userlogin с таким же браузером, как google add account. для этого вам нужно выполнить несколько шагов и перезаписать auth-библиотеку, предоставленную Laravel,

меры

Сделайте резервную копию вашего файла Auth.

Измените все функции хранилища сеансов, чтобы сначала сохранить их в массиве, а затем сохранить этот массив на сеанс

Теперь вам нужно создать новую переменную сеанса, которая будет хранить текущий идентификатор экземпляра пользователя, такой как user 0 1 2 …

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

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