Сессия потеряна при переключении с HTTP на HTTPS в PHP

При отправке пользователя на страницу проверки они переключаются с http://sitename.com на https://sitename.com .

В результате переменные $_SESSION теряются.

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

Solutions Collecting From Web of "Сессия потеряна при переключении с HTTP на HTTPS в PHP"

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

От PHP: session_start :

session_start() создает сеанс или возобновляет текущий на основе текущего идентификатора сеанса, который передается через запрос, например GET, POST или cookie

Когда вы используете сеансы, вы обычно запускаете свой скрипт с помощью session_start() . Если в браузере установлен файл cookie идентификатора сеанса, session_start() будет использовать этот идентификатор сеанса. Если в браузере нет набора cookie идентификатора сеанса, session_start() создаст новый.

Если идентификатор сеанса не установлен (в вашем примере браузер создает новый cookie идентификатора сеанса для сеанса HTTPS), вы можете установить его с помощью функции session_id() . session_id() также удобно возвращает идентификатор сеанса в виде строки. Так

 ... $currentSessionID = session_id(); ... 

устанавливает переменную $currentSessionID равную текущему идентификатору сеанса, и

 ... session_id($aSessionID); ... 

устанавливает cookie sessionID в браузере в значение $aSessionID . от PHP: session_id

Вот пример с двумя сценариями. Доступ к нему осуществляется через HTTP, а другой – через HTTPS. Они должны находиться на одном сервере для хранения данных сеанса.

Скрипт 1 (HTTP) :

 <?php // This script will create a session and display a link to your secure server address // to transfer your session ID. In this example, the secure page to receive the session // ID is located at http://www.yoursite.com/safePages/securePage.php // Start a session using the current session ID stored in a cookie, or create // a new session if none is set. session_start(); $currentSessionID = session_id(); // Set a variable that will be retrieved with the HTTPS script. $_SESSION['testvariable'] = 'It worked'; // $secureServerDomain is the domain of your secure server $secureServerDomain = 'www.yoursite.com'; // $securePagePath is the path to the page that will receive and set the session ID. $securePagePath = '/safePages/securePage.php' echo '<a href="https://' . $secureServerDomain . $securePagePath . '?session="' . $currentSessionID . '">Click here to transfer your session to the secure server</a>'; ?> 

Сценарий 2 (HTTPS) :

 <?php // Retrieve the session ID as passed via the GET method. $currentSessionID = $_GET['session']; // Set a cookie for the session ID. session_id($currentSessionID); // Start a session. session_start(); // Test retrieval of variable set when using HTTP. if (!empty($_SESSION['testvariable'])) { echo $_SESSION['testvariable']; } else { echo 'It did not work.'; } ?> 

Для этого серверы HTTP и HTTPS должны использовать одну и ту же среду хранения данных сеанса (т. Е. Для обработчика файлов по умолчанию, работать на одной физической машине с тем же php.ini). Здесь есть некоторые недостатки безопасности, поэтому я не буду использовать этот код для передачи конфиденциальной информации. Это просто пример работоспособности.

Когда я столкнулся с этой проблемой раньше, я придумал это как быстро исправить, но я только что вспомнил первоначальную причину проблемы. Я перешел с http://www.example.com/page.php на https://example.com/page.php (обратите внимание на отсутствие «www»). Убедитесь, что http://www.example.com/page.php будет ссылаться на https://www.example.com/page.php, а http://example.com будет ссылаться на https://example.com /page.php .

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

Похоже, что cookie сеанса настроен на безопасность. Cookies имеют «безопасный» флаг, который, если установлен в true, означает, что cookie не будет отправлен на сайты, отличные от https. PHP, вероятно, использует это для своих сессионных файлов cookie. Вы можете изменить это с помощью функции session_set_cookie_params или с параметром session.cookie_secure в php.ini.

У нас был этот вопрос. Это оказалось потому, что мы использовали патч suhosin на нашей установке PHP. Мы исправим его, установив suhosin.session.cryptdocroot = Off в /etc/php.d/suhosin.ini .

Для руководства suhosin о suhosin.session.cryptdocroot см. http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.cryptdocroot .

Мы изначально нашли исправление из этого сообщения в блоге: http://www.yireo.com/blog/general-news/315-switch-between-http-and-https-looses-php-session .

Следующее решение предполагает, что безопасные и незащищенные серверы имеют доступ к тем же бэкэнд-службам (кэш, хранилище базы данных и т. Д.).

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

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

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

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

Или, вероятно, ваш cookie сеанса не безопасен – просто URL-адрес страницы проверки отличается от другого ( http://mysite.com vs http://www.mysite.com ), что браузер не отправляет файл cookie.

Если вы хотите больше узнать о переходе с http на https и наоборот – обратите внимание на мою запись на выборочном ssl 🙂

Вы не можете передавать значения сеанса между разными доменами. Вы должны использовать http post-get или базу данных для передачи своих значений. Для обеспечения безопасности вы можете выполнить все ваши значения в строке и использовать

 sha1($string) 

и разместите его вместе со своими значениями и вычислите sha1 для значений, которые получает другая страница, а затем сравните хэши.

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

Использование url для метода get небезопасно, вам нужно будет запросить пароль на перенаправленной странице, чтобы позволить получать параметры в вашей системе.

Не используйте файлы cookie, если вам нужна безопасность.

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

 PAGE 1--- $key=sha1($allvalsconcat); //insert your session values to a database also the key in a column header("Location: page2.php?key=".$key); PAGE 2--- // select from database where key=$_GET["key"]; // delete from table where key=$key 

это довольно безопасно.

что может случиться: сценарий, вводящий случайные значения для параметра «ключ», чтобы ваш сайт загружал данные в вашу память?

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

вы можете установить тип движка таблицы в «память» в mysql, если хотите улучшить производительность.

Я бы рекомендовал в дополнение к тому, что большинство из них заявили о передаче зашифрованной информации, глядя на нее так же, как если бы вы передавали конфиденциальную информацию через сторонний API. Как вы знаете, что кто-то не подделывает запрос? Существует множество протоколов для подлинного подтверждения подлинности запроса, в зависимости от того, насколько чувствительна ваша настройка. Вы открываете себя, чтобы скомпрометировать аккаунты, если не будете осторожны.

Несмотря на то, что он находится на одном сервере, рассмотрите следующее:

Когда кто-то следит за ссылкой, формирует действие и т. Д., Которое проходит через зашифрованный ключ, что помешает кому-то обнюхать его до того, как они попадут в защищенную версию вашего сайта? Если бы я был на публичном месте WIFI, это не было бы слишком надуманным. Я мог бы притворяться вашим сайтом, перенаправлять запросы на свой собственный ноутбук, захватить токен и перенаправить посетителя туда, где они пришли. Они предполагали, что это был глюк, и понятия не имел. Теперь я могу войти в систему как они, и, возможно, пойду купить вещи стоимостью 10 000 долларов со своей кредитной карточкой и отправить ее в другое место. Степень осторожности, которую вы принимаете здесь, должна соответствовать степени чувствительности.

Кроме того, убедитесь, что вы истекли токены (один используется только после X числа секунд и т. Д.), Но я также хотел бы использовать шаблон Post-Redirect-Get на обоих концах, то есть:

Не показывайте прямую ссылку на странице или в виде незащищенного сайта, но показывайте ссылку, которая затем перенаправляет на бэкэнд (и обрабатывает все данные маркера / шифрования). Когда вы придете к защищенной версии, сделайте то же самое (не оставляйте параметр «? Токен = asdfjalksfjla», просто сидите там в URL-адресе, перенаправляйте его).

Таким образом, формальные системы на основе токенов были разработаны для решения этой самой проблемы, но реализация OAuth только для этого может быть чрезмерной. Проведите некоторое время, планируя потенциальные уязвимости перед выполнением. Просто потому, что было бы очень трудно догадаться, что токен не означает, что это невозможно (или не могло быть столкновений и т. Д.), Поэтому планируйте соответственно.

Вам также может потребоваться более сложная система управления сеансом, чем встроенные обработчики PHP. Я не знаю, можете ли вы заставить PHP продолжать сеанс через несколько посещений (таким образом обрабатываются протоколы переключения).

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

Если SSL для всех страниц не является для вас вариантом, вы можете использовать этот подход: Переключение между страницами HTTP и HTTPS с помощью безопасного сеансового файла cookie . Идея заключается в том, что вы оставляете cookie сессии незащищенным (и, следовательно, доступным для страниц HTTP и HTTPS), но имеете второй защищенный cookie для обработки аутентификации. Это хороший способ разделить две проблемы: «сохранение сеанса» и «аутентификация».

Вы можете управлять сеансом между HTTP и HTTPS или HTTPS по протоколу HTTP:

  1. Идентификатор сеанса передачи между страницей с использованием GET

  2. Идентификатор сеанса POST по POST

  3. Использовать файлы для сохранения сеансов

  4. Использовать файлы cookie для сеансов

  5. Использовать базу данных для сохранения сеанса

Ниже пример может использоваться для передачи с использованием GET ….

Файл: http.php ……………

 <?php session_start(); $sessionID = session_id(); $_SESSION['demo'] = 'Demo session between HTTP HTTPS'; echo '<a href=”https://www.svnlabs.com/https.php?session='.$sessionID.'”>Demo session from HTTP to HTTPS</a>'; ?> 

Файл: https.php ……………

 <?php $sessionID = $_GET['session']; session_id($sessionID); session_start(); if (!empty($_SESSION['demo'])) { echo $_SESSION['svnlabs']; } else { echo 'Demo session failed'; } ?> 

IE7: эта страница содержит как безопасные, так и небезопасные элементы

Вы должны использовать относительный путь для всех статических ресурсов на странице, например, css, js, images, flash и т. Д., Чтобы избежать безопасного и небезопасного сообщения IE.

Сообщение IE Сообщение IE

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

Какой браузер вы используете?

По умолчанию я ожидал бы, что браузер будет рассматривать соединения с http и https как совершенно разные сеансы. Хотя соглашение заключается в том, что http: // someUrl / и https: // someUrl / укажет на одну и ту же страницу, это не гарантируется. У вас могут быть совершенно разные сайты, работающие на порту 80 (http) и порту 443 (https).

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

Простите не авторитарный ответ, но я думал, что запишу в своем 2c, так как ответов не так много.

У вас есть выделенный IP-адрес? в некоторых общих средах https и http маршрутизируются через разные серверы, поэтому переключение фактически теряет доступ к файлам cookie, поскольку они находятся в разных доменах.

решениями будут: выделенный ip

принудительное включение https на всех страницах

У меня была аналогичная проблема, однако, это решение было полезно для меня, возможно, поможет другим в будущем

добавьте это в свой php.ini

suhosin.session.cryptdocroot = Выкл.

suhosin.cookie.cryptdocroot = Выкл.

У меня есть решение этого … Попробуйте.

 $_SESSION['test'] = 'test'; session_regenerate_id(true); header("Location: /");// the header must be sent before session close session_write_close(); // here you could also use exit(); 

Не беспокойтесь, это нормальное поведение, потому что HTTPS предназначен для обеспечения безопасности, и он делает свою часть.

Ниже приведены некоторые трюки, через которые вы можете поддерживать сеанс при переключении с HTTP на HTTPS.

  1. Идентификатор сеанса передачи между страницей с использованием GET

  2. Идентификатор сеанса POST по POST

  3. Использовать файлы для сохранения сеансов

  4. Использовать файлы cookie для сеансов

  5. Использовать базу данных для сохранения сеанса

Надеюсь, что вы получите что-то в моем ответе.