Сеанс PHP втрачено після переадресації


132

Як вирішити проблему втрати сеансу після переадресації на PHP?

Нещодавно я зіткнувся з дуже поширеною проблемою втрати сеансу після переадресації. І після пошуку цього веб-сайту я все ще не можу знайти рішення (хоча це було найближчим).

Оновлення

Я знайшов відповідь, і я подумав, що опублікую її тут, щоб допомогти будь-кому, хто відчуває ту саму проблему.


1
Питання полягає в тому, як вирішити проблему втрати сеансу після перенаправлення в PHP. Я вже зрозумів відповідь, просто розмістивши її тут, щоб повідомити інших людей. Тому що моє рішення не в StackOverflow.
dayuloli

2
Це добре, але це QA-сайт. Будь ласка, поставте своє запитання.
jeremy

Я не помітив, що це від вас. Все-таки цей сайт призначений для запитань, а не для відповідей на питання, які ви вже знаєте.
Аріс


21
@Aris Це неправда, коли у людей виникає запитання щодо кодування, вони приходять до StackOverflow за допомогою. Якщо відповіді немає, вони не можуть отримати необхідну допомогу. Я намагаюся надати цю відповідь.
dayuloli

Відповіді:


208

Спочатку проведіть такі звичайні перевірки:

  1. Переконайтеся, що session_start();дзвонено перед тим , як викликати будь-які сеанси. Тож надійною ставкою було б розмістити її на початку своєї сторінки, одразу після вступної <?phpдекларації перед чим-небудь іншим. Також переконайтесь, що немає пробілів / вкладок перед початковою <?phpдекларацією.
  2. Після headerпереадресації закінчіть поточний сценарій, використовуючи exit();(інші також запропонували, session_write_close();і session_regenerate_id(true)ви можете спробувати і цей, але я б і використовував exit();)
  3. Переконайтеся, що куки cookie увімкнено в браузері, який ви використовуєте для тестування.
  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" - це шлях до вашого домашнього каталогу. І звичайно, переконайтеся, що папка насправді існує у вашому кореневому каталозі. (Деякі програми не завантажують порожні папки під час синхронізації)


8
Дуже добре написано +1, якщо все не вдалося, просто використовуйте файли cookie (випадково генеруйте рядок і зберігайте їх у db та використовуйте це як значення файлу cookie).
Дейв Чен

2
перемикання між HTTP і п HTTPS може бути також є проблемою stackoverflow.com/questions/441496 / ...
dev.e.loper

4
Зауважте, що з php 5.4.0 register_globals було видалено, тому це більше не спричинить проблеми
anthonygore

2
Перевірте також журнал помилок веб-сервера; у моєму випадку сталася помилка "Не вдалося записати дані сесії (файли). Перевірте, чи правильний параметр session.save_path правильний". В каталозі save_path дозволи не було дозволено.
timbonicus

Будь-яка причина, чому мої сеанси зберігатимуться десь іншим, ніж у session.save_path?
Джастін

26

ви повинні використовувати "вихід" після виклику заголовка

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

Існує помилка для Gecko (наприклад, Waterfox, Firefox, SeaMonkey), якщо якщо є якийсь вихід даних (наприклад echo ' ';) або пробіл будь-якого типу, він повністю ігнорує заголовок розташування.
Іоанн

18

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

Врешті-решт, я вирішив проблему, використовуючи 'відносний URL' всередині заголовка переадресації!

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

анулював файли cookie сеансу

header("location: index.php")

працював як шарм!


7

У мене була така ж проблема. Я працював над цим кілька годин, і це зводило мене з розуму.

У моєму випадку проблема полягала у виклику 404 через відсутність favicon.ico лише у Chrome та Firefox. Інші навігатори працювали чудово.


Просто хотів подякувати вам за цю відповідь, змусив мене зрозуміти, що 404 запитів для зображень Varnish пересилає до PHP без будь-яких файлів cookie. Може, ніколи не зрозумів це без тебе.
Паскаль Заяк

У мене була така ж проблема, мій favicon.ico переспрямовувався (перенаправлення 302 з піддомену на основний домен), і таким чином, кожен раз створював новий сеанс. Дуже дякую!
simdrouin

4

Коли я використовую відносний шлях "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")

3

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

session.use_cookies = 1 

Я думав, що сеанси працюють без печива ... насправді я знаю, що вони ДОЛЖНІ ... але це вирішило мою проблему принаймні, поки я не можу зрозуміти, що може йти в більшій картині.


Я не знав, що сеанси можуть працювати без файлів cookie! Дізнайтеся щось нове щодня! programmerinterview.com/index.php/php-questions/…
dayuloli

звичайно, вони МОЖУТЬ працювати без cookies, залежить від вашої конфігурації. Але ви повинні знати, що ви робите. І для цього є вагома причина. Тому що це менш безпечно. і якщо вам доведеться працювати з будь-якої причини без печива. Ви повинні принаймні налаштувати ini_set ('session.use_strict_mode', '1'); і зазвичай мають короткий час сеансу, і після входу користувача використовуйте session_regenerate_id (). Але будьте попереджені, якщо якийсь користувач розмістить посилання на сайт на вашому сервері на форумі, люди, які насправді натискають на це посилання, перейдуть на сеанс. Можливо, перевірка ip також є хорошою ідеєю.
Майкл

3

У мене була схожа проблема, хоча мій контекст був дещо іншим. У мене було налаштовано локальну розробку на машині, ім'я хоста windowsта IP-адреса 192.168.56.2.

Я мав доступ до системи за допомогою будь-якого з:

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

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

Якщо попереднього доменного імені, використовуваного для доступу до системи, не було windows, дані сеансу втрачаються. Я вирішив це, змінивши код на:

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

Тепер він працює незалежно від того, яке місцеве доменне ім’я або IP-адреса вводить користувач.

Я сподіваюся, що це може бути корисним комусь.


3

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

Нарешті я зрозумів, що саме на цій сторінці я знищував сеанс на початку сторінки, але ніколи не запускав її знову. Тож моя функція знищення змінилася з:

function sessionKill(){

    session_destroy();

}

до:

function sessionKill(){

    session_destroy();
    session_start();

}

І все спрацювало!


3

У мене була така ж проблема. Зненацька ДЕЯКІ мої змінні сеансу не збережуться на наступній сторінці. Проблема виявилася (у php7.1), що у заголовку ви не повинні містити WWW, наприклад https: // mysite . добре, https: //www.mysite . втратить змінні сеансу сторінок. Не всі, лише ця сторінка.


Це тому www.mysite.com, що розглядається як абсолютно інший домен, ніж blog.mysite.comабо простоmysite.com
dayuloli

2

Я боровся з цим цілими днями, перевіряючи / пробуючи всі рішення, але моя проблема полягала в тому, що я не дзвонив session_start();знову після переадресації. Я просто припустив, що сеанс "ще живий".

Тож не забувайте цього!


Так! це була і моя проблема. Я думав, що почати сеанс PHP - це як увімкнути світло для всього будинку. Я не усвідомлював, що потрібно увімкнути вимикач для кожної кімнати, в яку ти входиш.
Дейл Томпсон

1

У мене була така ж проблема і знайшов найпростіший спосіб. Я просто перенаправлений на переспрямування .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;

Я сподіваюся, що це допомагає.

Любов грам


1

Якщо ви користуєтесь, session_set_cookie_params()ви можете перевірити, чи передаєте ви четвертий парам $secureяк true. Якщо ви є, то вам потрібно отримати доступ до URL за допомогою https.

$secureПари бути істинним засобом сеанс доступні тільки в безпечному запиті. Це може вплинути на вас локальніше більше, ніж на сценічних або виробничих умовах.

Згадуючи про це, бо я щойно витратив більшість сьогодні, намагаючись знайти це питання, і саме це вирішило для мене. Мене щойно додали до цього проекту, і ніхто не згадував, що він вимагає https.

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

В залежності від вашого локального сервера, ви , можливо , доведеться редагувати DocumentRootв httpd-ssl.confсервера , так що локальний URL обслуговується по протоколу HTTPS.


1

Ще одна можлива причина:

Це мій простір для зберігання сервера. Дисковий простір мого сервера стає повноцінним. Отже, я видалив декілька файлів і папок на своєму сервері і спробував.

Це працювало !!!

Я зберігаю свій сеанс в AWS Dynamo DB, але він все ще очікує, що на моєму сервері буде простір для сеансу. Не знаю чому !!!


1

Якщо ви використовуєте Laravel і відчуваєте цю проблему, вам потрібно зберегти дані сеансу перед перенаправленням.

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

0

У мене також була проблема з тим, що переспрямування не працює, і я спробував усі рішення, які я міг знайти, моє переспрямування заголовка використовувалося у формі.

Я вирішив це, поставивши перенаправлення заголовка в іншу сторінку php 'signingery.php' та передавши параметри змінних через потрібні параметри url, а потім переназначивши їх у формі 'signingery.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);

signingery.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';
}

?>

Це не красива обробка, але вона спрацювала.


0

Для мене помилка полягала в тому, що я намагався зберегти в сеансі несеріалізіруемый об'єкт, щоб під час написання сеансу було викинуто виняток. Але оскільки мій код обробки помилок вже припинив будь-яку операцію, я жодної помилки не бачив.

Я можу знайти його в журналах помилок Apache.


0

Тільки для запису ... У мене була ця проблема, і через кілька годин спробував усе, проблема полягала в тому, що диск був повний, а сеанси php не вдалося записати в каталог tmp ... так що якщо у вас є ця проблема, перевірте, що теж ...


Ця відповідь спрацювала на мене. Ми запускаємо зображення машини Amazon з nginx. Здається, є помилка в тому, що папка сеансу не належить правильному користувачеві (в нашому випадку www), тому виконання chown -R www.wwwв папці сеансів усуває проблему.
Джошуа

0

Для мене Firefox зберігає ідентифікатор сеансу (PHPSESSID) у файлі cookie, але Google Chrome використовував параметр GET або POST. Тож вам потрібно лише переконатися, що скрипт, що повертається (для мене: paypal checkout), виконує PHPSESSID в URL-адресі або параметрі POST.


0

Спробувавши багато рішень тут на SO та інших блогах ... те, що працювало для мене, було додавання .htaccess до кореня мого веб-сайту.

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

0

Якщо ви використовуєте Wordpress, мені довелося додати цей гачок і почати сеанс на init:

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

0

Ніщо не працювало для мене, але я виявив, що викликало проблему (і вирішило її):

Перевірте файли cookie свого веб-переглядача та переконайтеся, що у різних субдоменах немає файлів cookie-сеансів PHP (наприклад, для " www.website.com " та одного для " website.com ").

Це було викликано javascript, який неправильно використовував піддомен для встановлення файлів cookie та відкриття сторінок у iframes.


0

Перш за все, переконайтеся, що ви телефонуєте, session_start()перш ніж використовувати $_SESSIONзмінну.

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

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

Найпоширеніші причини, про які не йдеться у відповіді @ dayuloli:

  1. Проблема з дисковим простором. Переконайтеся, що на диску не заповнено, вам потрібно трохи місця для зберігання сесійних файлів.

  2. Каталог сеансів може бути недоступним для запису. Ви можете це перевіритиis_writable(session_save_path())


0

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

Отже, якщо хтось читає це, будь-ласка, перевірте php.iniконфігурацію.


0

Переконайтеся, що session_write_closeне називається між session_start()і коли ви встановлюєте сеанс.

session_start();

[...]

session_write_close();

[...]

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

0

Тепер, коли GDPR - це річ, люди, які відвідують це питання, ймовірно, використовують сценарій cookie. Що ж, цей сценарій спричинив проблему для мене. Мабуть, PHP використовує файл cookie, який називається PHPSESSIDдля відстеження сеансу. Якщо цей сценарій видаляє його, ви втрачаєте свої дані.

Я використав цей сценарій cookie . У ньому є можливість включити "необхідні" файли cookie. Я додав PHPSESSIDдо списку, скрипт перестав видаляти файли cookie, і все почало працювати знову.

Можливо, ви можете включити деякі параметри PHP, щоб уникнути використання PHPSESSID, але якщо ваш сценарій cookie є причиною проблеми, чому б не виправити це .


0

Я вирішив цю проблему після багатьох днів налагодження, і це було все тому, що в моїй зворотній URL-адресі, отриманій від PayPal Express Checkout, не було "www". Chrome визнав, що домени слід обробляти однаково, але іноді інші веб-переглядачі цього не роблять. Використовуючи сеанси / файли cookie та абсолютні шляхи, не забувайте "www"!


0

Я виправив, надавши дозволу на групове записування до шляху, де PHP зберігає файли сеансу. Ви можете знайти шлях до сеансу за допомогою функції session_save_path ().


0

Сьогодні у мене була проблема в проекті, і мені довелося змінити цей параметр на хибний (або видалити рядки, за замовчуванням вимкнено):

ini_set( 'session.cookie_secure', 1 );

Це сталося тому, що власне проект працює над http, а не тільки https. Додаткову інформацію можна знайти в документах http://php.net/manual/en/session.security.ini.php


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

Надто пізно відповісти, але це працювало для мене


0

Для мене це була помилка дозволу, і це вирішило:

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);

і він друкував порожній масив.

У цей момент я подумав, що це може бути проблема сервера, і насправді це було.

Сподіваюся, що це комусь допоможе.


1
Чуун - це рішення BAD, оскільки воно буде змінено назад до значення за замовчуванням при оновленні пакета. Дивіться коментарі в конфігурації пулу за замовчуванням (www.conf). Правильний спосіб, якщо використовувати інший каталог, ніж apache one (наприклад: / var / lib / php / nginx / session)
Remi Collet

Ти правий. оновлення пакета стало причиною моєї проблеми в першу чергу. Але оскільки це було зроблено, і мені було потрібно швидке рішення, це допомогло. Мій адміністратор SYS вирішив це, я не дуже добрий з Linux.
тем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.