Сессия PHP потеряна после перенаправления

Как решить проблему потери сеанса после перенаправления в PHP?

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

Обновление

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

Ответ 1

Сначала выполните эти обычные проверки:

  1. Убедитесь, что session_start(); вызывается до вызова любых сеансов. Поэтому безопаснее было бы поместить его в начало вашей страницы, сразу после открытия <?php декларации, прежде чем что-либо еще. Также убедитесь, что перед открывающей декларацией <?php нет пробелов/табуляций.
  2. После перенаправления header завершите текущий скрипт, используя exit(); (Другие также предложили session_write_close(); и session_regenerate_id(true), вы также можете попробовать их, но я бы использовал exit();)
  3. Убедитесь, что куки включены в браузере, который вы используете для тестирования.
  4. Убедитесь, что register_globals выключена, вы можете проверить это в файле php.ini а также с помощью phpinfo(). Обратитесь к этому как к тому, как выключить это.
  5. Убедитесь, что вы не удалили или не очистили сеанс
  6. Убедитесь, что ключ в вашем суперглобальном массиве $_SESSION нигде не перезаписан
  7. Убедитесь, что вы перенаправляете на тот же домен. Таким образом, перенаправление с www.yourdomain.com на yourdomain.com не переносит сеанс вперед.
  8. Убедитесь, что ваше расширение файла .php (это происходит!)

Сейчас это наиболее распространенные ошибки, но если они не сработали, проблема, скорее всего, связана с вашей хостинговой компанией. Если все работает на localhost но не на вашем удаленном/тестовом сервере, то это, скорее всего, виновник. Поэтому проверьте базу знаний вашего хостинг-провайдера (также попробуйте их форумы и т.д.). Для таких компаний, как FatCow и iPage, они требуют, чтобы вы указали session_save_path. Ну вот так:

session_save_path('"your home directory path"/cgi-bin/tmp');
session_start();

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

<?php echo $_SERVER['SCRIPT_FILENAME']; ?>

Бит перед test.php - это путь к вашему домашнему каталогу. И конечно, убедитесь, что папка действительно существует в вашем корневом каталоге. (Некоторые программы не загружают пустые папки при синхронизации)

Ответ 2

вы должны использовать "exit" после заголовка

header('Location: http://www.example.com/?blabla=blubb');
exit;

Ответ 3

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

В конце концов, я столкнулся с проблемой, используя "относительный url" внутри заголовка перенаправления!

header("location: http://example.com/index.php")

аннулирует файлы cookie сеанса

header("location: index.php")

работал как шарм!

Ответ 4

У меня была та же проблема. Я работал над ним несколько часов, и это сводило меня с ума.

В моем случае проблема была вызвана 404 из-за отсутствующего favicon.ico только в Chrome и Firefox. Другие навигаторы отлично работали.

Ответ 5

Это заставило меня долгое время (и этот пост был замечателен, чтобы найти!), но для тех, кто еще не может получить сеансы между переадресацией страниц на работу... Мне пришлось зайти в файл php.ini и включить cookies:

session.use_cookies = 1 

Я думал, что сеансы работают без файлов cookie... на самом деле я знаю, что они ДОЛЖНЫ... но это исправляло мою проблему хотя бы до тех пор, пока я не пойму, что может происходить на более широкой картине.

Ответ 6

У меня была аналогичная проблема, хотя мой контекст несколько отличался. У меня была локальная настройка разработки на машине с именем хоста windows, а IP-адрес был 192.168.56.2.

Я мог бы получить доступ к системе, используя любой из:

После входа в систему мой PHP-код будет перенаправляться с помощью:

header('http://windows/');

Если предыдущее имя домена, используемое для доступа к системе, не было windows, данные сеанса будут потеряны. Я решил это, изменив код на:

header('http://'.$_SERVER['HTTP_HOST'].'/');

Теперь он работает независимо от того, какое имя локального домена или IP-адрес помещает пользователь.

Я надеюсь, что это может быть полезно кому-то.

Ответ 7

Я столкнулся с этой проблемой на одной конкретной странице. Я задавал значения $_SESSION на других страницах перед перенаправлением, и все работало нормально. Но эта страница не работала.

Наконец, я понял, что на этой странице я уничтожал сессию в начале страницы, но не начинал ее снова. Поэтому моя функция уничтожения изменилась с:

function sessionKill(){

    session_destroy();

}

в

function sessionKill(){

    session_destroy();
    session_start();

}

И все сработало!

Ответ 8

У меня была такая же проблема. Неожиданно из моих переменных сеанса не сохранилась следующая страница. Проблема оказалась (в php7.1) у вашего местоположения заголовка не должно быть WWW, ex https://mysite. нормально, https://www.mysite. потеряет эти переменные сеанса страницы. Не все, только эта страница.

Ответ 9

У меня была такая же проблема, и я нашел самый простой способ. Я просто перенаправлен на перенаправление .html с 1 строкой JS

<!DOCTYPE html>
<html>
<script type="text/javascript">
<!--
window.location = "admin_index.php";
//–>
</script>
</html>

вместо PHP

header_remove();
header('Location: admin_login.php');
die;

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

Любовь Gram

Ответ 10

Я боролся с этим в течение нескольких дней, проверяя/пытаясь все решения, но моя проблема заключалась в том, что я снова не вызывал session_start(); после перенаправления. Я просто предположил, что сеанс "все еще жив".

Так что не забывайте об этом!

Ответ 11

Если вы используете session_set_cookie_params(), вы можете проверить, проходите ли вы четвертый параметр $secure как true. Если да, то вам нужно получить доступ к URL-адресу с помощью https.

Параметр $secure, являющийся истинным, означает, что сеанс доступен только в защищенном запросе. Это может повлиять на вас локально больше, чем на сцене или в производственной среде.

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

Таким образом, вы можете использовать https локально, или вы можете установить параметр $secure в FALSE, а затем использовать http локально. Просто убедитесь, что вернетесь к истине, когда вы нажимаете свои изменения.

В зависимости от вашего локального сервера вам может потребоваться отредактировать DocumentRoot в httpd-ssl.conf сервера, чтобы ваш локальный URL был отправлен https.

Ответ 12

Другая возможная причина:

Это мое хранилище на сервере. Мое пространство на сервере становится полным. Итак, я удалил несколько файлов и папок на моем сервере и попытался.

Это сработало!!!

Я сохраняю сеанс в базе данных AWS Dynamo, но он все еще ожидает некоторого пространства на моем сервере для обработки сеанса. Не уверен, почему!!!

Ответ 13

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

session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;

Ответ 14

Когда я использую относительный путь "dir/file.php" с в функции header() в работает для меня. Я думаю, что сессия не сохраняется по какой-то причине, когда вы перенаправляете, используя полный URL-адрес...

//Does retain the session info for some reason
header("Location: dir");

//Does not retain the session for some reason
header("Location: https://mywebz.com/dir")

Ответ 15

У меня также была такая же проблема с тем, что перенаправление не работало, и попробовал все решения, которые я мог найти, моя перенаправляющая строка использовалась в форме.

Я решил это, поставив переадресацию заголовка на другую php-страницу "signin_action.php" и передав параметры переменных через нужные параметры url, а затем переназначив их в форме "signin_action.php".

signin.php

if($stmt->num_rows>0) {
$_SESSION['username'] = $_POST['username'];
echo '<script>window.location.href = "http://'.$root.'/includes/functions/signin_action.php?username='.$_SESSION['username'].'";</script>';
error_reporting(E_ALL);

signin_action.php

<?php
require('../../config/init.php');
$_SESSION['username'] = $_GET['username'];
if ($_SESSION['username']) {

echo '<script>window.location.href = "http://'.$root.'/user/index.php";</script>';
exit();
} else {
echo 'Session not set';
}

?>

Это не красивая работа, но она сработала.

Ответ 16

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

Я мог бы найти его в журналах ошибок Apache.

Ответ 17

Просто для записи... У меня возникла эта проблема, и через несколько часов я попробовал все, что проблема была в том, что диск был заполнен, а сеансы php не могли быть записаны в каталог tmp... так что если у вас есть это проверьте проблему тоже...

Ответ 18

Для меня Firefox хранит идентификатор сеанса (PHPSESSID) в файле cookie, но Google Chrome использует параметр GET или POST. Поэтому вам нужно только убедиться, что возвращаемый script (для меня: paypal checkout) зафиксирует PHPSESSID в URL-адресе или параметре POST.

Ответ 19

Попробовав много решений здесь на SO и других блогах... то, что работало для меня, добавляло .htaccess к моему корню сайта.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursitename.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursitename\.com" [R=301,L]

Ответ 20

Если вы используете Wordpress, мне пришлось добавить этот крючок и начать сеанс в init:

function register_my_session() {
    if (!session_id()) {
        session_start();
    }
}
add_action('init', 'register_my_session');

Ответ 21

Ничего не работало для меня, но я нашел причину проблемы (и решил ее):

Проверьте файлы cookie браузера и убедитесь, что в разных поддоменах нет файлов cookie php сессии (например, для " www.website.com", а для " website.com" ).

Это было вызвано javascript, который неправильно использовал субдомен для установки файлов cookie и для открытия страниц в iframe.

Ответ 22

Прежде всего, убедитесь, что вы вызываете session_start() перед использованием переменной $_SESSION.

Если вы отключили отчет об ошибках, попробуйте включить его и увидеть результат.

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Наиболее распространенные причины, которые не упоминаются в ответе @dayuloli:

  • Проблема с дисковым пространством. Убедитесь, что ваше дисковое пространство не заполнено, вам нужно место для хранения файлов сеанса.

  • Каталог сессий может быть недоступен для записи. Вы можете проверить его с помощью is_writable(session_save_path())

Ответ 23

У меня была та же проблема, и я сошел с ума, ища ответ в своем коде. Наконец, я обнаружил, что мой хостинг недавно обновил версию PHP на моем сервере и неправильно настроил параметр session_save_path в файле php.ini.

Так что, если кто-то читает это, пожалуйста, проверьте конфигурацию php.ini прежде чем что-либо еще.

Ответ 24

Убедитесь, что session_write_close не вызывается между session_start() и когда вы устанавливаете сеанс.

session_start();

[...]

session_write_close();

[...]

$_SESSION['name']='Bob'; //<-- won't save

Ответ 25

Теперь, когда GDPR - вещь, люди, посещающие этот вопрос, вероятно, используют скрипт cookie. Ну, этот сценарий вызвал проблему для меня. Очевидно, PHP использует cookie файл PHPSESSID для отслеживания сеанса. Если этот скрипт удалит его, вы потеряете ваши данные.

Я использовал этот скрипт cookie. Он имеет возможность включить "необходимые" куки. Я добавил PHPSESSID в список, скрипт перестал удалять cookie, и все снова заработало.

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

Ответ 26

Я исправил эту проблему после многих дней отладки, и все из-за того, что у моего обратного URL, полученного от PayPal Express Checkout, не было "www". Chrome признал, что к доменам следует относиться одинаково, но другие браузеры иногда этого не делают. При использовании сессий/файлов cookie и абсолютных путей не забывайте "www"!

Ответ 27

Я исправил это, дав групповым разрешениям на запись путь к файлам сессий в PHP. Вы можете найти путь к сессии с помощью функции session_save_path().

Ответ 28

Сегодня у меня была эта проблема в проекте, и мне пришлось изменить этот параметр на false (или удалить строки, по умолчанию отключено):

ini_set( 'session.cookie_secure', 1 );

Это произошло потому, что сам проект работает по протоколу http, а не только по протоколу https. Более подробную информацию можно найти в документации http://php.net/manual/en/session.security.ini.php

Ответ 29

ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
session_start();

Слишком поздно, чтобы ответить, но это сработало для меня

Ответ 30

Для меня это была ошибка разрешения, и это решило ее:

chown -R nginx:nginx/var/opt/remi/php73/lib/php/session

Я провёл несколько часов на PHP, и последний тест, который я провел, - это создание двух файлов session1.php и session2.php.

session1.php:

session_start();

$_SESSION["user"] = 123;

header("Location: session2.php");

session2.php:

session_start();

print_r($_SESSION);

и он печатал пустой массив.

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

Надеюсь, это кому-нибудь поможет.