Задать вопрос
@photosho

Почему для сохранения сессии требуется перезагрузка страницы?

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

Создаю форму авторизации посредством AJAX - это не форма в терминах HTML, она не отправляется кнопкой "Submit", но AJAX делает некоторый запрос к серверу, сервер, в свою очередь, проверяет правильность введенных данных, и, если все введено правильно, вызывает код авторизации пользователя:

$result = \Auth::attempt([
  'username' => $login,
  'password' => $password
], $remember);


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

Интересно, что если после вышеприведенного кода вызвать функцию перенаправления, то сессия создастся правильно:

if ($result) return redirect()->intended('/');

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

Если отлавливать это сообщение (302) и обновлять страницу в браузере при его получении, то страница обновится быстро, и сервер еще не успеет обработать перенаправления в своем скрипте, в результате чего на экране будет все та же кнопка входа, и только после еще одной перезагрузки страницы мы увидим надпись "Вы вошли".

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

В результате, вопрос: что такое делает сервер перед своей перезагрузкой, что позволяет ему сохранить сессию (почему она не сохраняется функцией "attempt", и требуется обязательная перезагрузка) и можно ли эти действия вызвать внутри вызываемого при помощи AJAX скрипта?
  • Вопрос задан
  • 2020 просмотров
Подписаться 1 Оценить 11 комментариев
Решения вопроса 1
@photosho Автор вопроса
При каждом обновлении страницы создается 2 записи Cookie: "XSRF-TOKEN" и "laravel_session". При обычном AJAX-запросе на авторизацию больше Cookie не создается. При AJAX-запросе с последующим перенаправлением PHP-скрипта на любую страницу - в браузере появляется еще одна запись Cookie. Все записи привязаны к корневой директории сайта ("/").

Притом, после такого запроса страница, с которой была произведена авторизация, получает ответ на свой POST-запрос с кодом "302" + какой-то удачный GET-запрос с того адреса, куда было произведено перенаправление PHP-скрипта.

Не знаю, насколько это правильно, но из всего перечисленного делаю вывод, что финальное перенаправление PHP-скрипта нужно для обновление записи Cookie в браузере (каким образом - пока не знаю), а значит, и подтверждения авторизации. Без этой записи в Cokie пользователь не мог считаться авторизованным, и простая перезагрузка страницы в браузере, будто бы, "удаляла авторизацию". Почему пользователь при этом считался авторизованным в той же сессии - пока тоже не знаю, возможно, информация о нем как-то кешировалась в переменных на сервере.

Решил проблему следующим образом. Так как после перенаправления PHP-скрипта на сервере открытой странице с формой авторизации возвращался GET-запрос, сделал вывод, что страница, на которую идет перенаправление, все еще связана с нашей AJAX-функцией. Поэтому перенаправление в PHP-скрипте поставил на страницу "/login/final/", где записал единственную строку:

echo json_encode(['redirect' => 'update']);

Как и предвидел: этот массив после выполнения скрипта возвратился браузеру, и по значению "update" параметра "redirect" браузер обновляет текущую страницу. Авторизация работает.

Всем спасибо за помощь, совет "заглянуть в Cookie" направил меня по нужному пути.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Nc_Soft
/**
         * Attempt to authenticate a user using the given credentials.
         *
         * @param array $credentials
         * @param bool $remember
         * @param bool $login
         * @return bool 
         * @static 
         */
        public static function attempt($credentials = array(), $remember = false, $login = true){
            return \Illuminate\Auth\Guard::attempt($credentials, $remember, $login);
        }

Должно сразу авторизовывать, у вас что-то с сессиями/куками
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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