Я знаю, что судя по названию, на этот вопрос здесь несколько раз ответили, но ни один из постов не предлагает мне правильного решения. Итак, я иду:
ПРОБЛЕМА:
У меня есть и файл index.php. Это простая html-форма с полями пользователя / пароля и кнопкой входа в систему. При нажатии кнопки входа в систему функция с именем login () генерирует хеш для пароля. Затем пользователь + хэш сверяется с базой данных. Если доступ действителен, я добавляю некоторые значения в SESSION, возвращает true, а затем форма загружает файл php с именем process_login.php, где все, что я делаю, это проверяю, является ли пользователь администратором или нет, и загружаю другой веб-сайт в соответствии с тот. Все идет нормально.
Process_login.php загружает нужный веб-сайт и может видеть значения SESSION (я пытался их распечатать, все в порядке).
Эти значения используются, чтобы проверить, есть ли у текущего пользователя действительный сеанс (вошел в систему) перед загрузкой любого веб-сайта. Вот как я добавляю переменные в SESSION, кстати
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $user);
$_SESSION['user_id'] = $user_id;
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $db_password . $user_browser);
Вот и проблема: process_login.php загружает правильный веб-сайт home.php. Затем Home.php проверяет, действителен ли сеанс, с помощью функции с именем login_check (). первая строка этой функции
// Check if all session variables are set
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
И это не удается. SESSION - пустой массив, и я не знаю почему.
Читая возможные причины, люди всегда предлагают вызывать start_session () в начале каждого файла php, где нам нужно использовать SESSION. Хорошо, я знаю. Я называю его index.php, process_login.php и home.php, но ... ничего. Единственное место, где я его не называю, - это functions.php, который я использую для объявления всех функций, упомянутых выше. это просто включенный файл, там ничего не загружается.
Вот как я начинаю сеанс:
function sec_session_start() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = SECURE;
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start(); // Start the PHP session
session_regenerate_id(); // regenerated the session, delete the old one.
}
Затем, в начале каждого файла, я устанавливаю этот фрагмент кода (код может немного отличаться, потому что включаемые файлы могут быть разными)
<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
?>
Как видите, в конце я вызываю session_regenerate_id (). Я подозревал, что, возможно, он удаляет все в моей СЕССИИ, поэтому я прокомментировал это. Ничего не изменилось. home.php продолжает не видеть то, что находится в SESSION.
Любая помощь будет очень высоко ценится. При необходимости я могу предоставить больше кода. Кроме того, стоит упомянуть, что это не работает как локально (XAMPP), так и онлайн (веб-хостинг).
Ваше здоровье
ОБНОВИТЬ:
При создании SESSION я использую функцию session_set_cookie_params () для его настройки. Параметр SECURE - это определенный логический объект, для которого установлено значение true. Если я изменю его на FALSE, все будет работать нормально. Я понимаю, что XAMPP не может использовать https (если вы не установите сертификат и т. д.), Но я ожидаю, что это будет работать на сервере (он использует защищенные соединения ssh, поэтому https). Двойная проверка переадресации с использованием https.
Следует отметить, что session_start() следует вызывать до генерации каких-либо выходных данных - это действительно включает сообщения об ошибках.
Включите отчеты об ошибках и сообщите нам, что вы получите в ответ. php.net/manual/en/function.error-reporting.php
Вы отметили "html-form", где эта форма? И как ранее говорилось о SECURE. Я так понимаю, вы приписали то, что где-то считается константой? Ваш вопрос непонятен.
Привет! Хорошо, отвечая всем вам: Дарраг: спасибо, не заметил этого. Я собираюсь это еще раз проверить. Есть код, который я не писал, так что это может быть ошибка. По поводу ошибок: ошибок нет вообще. Я слежу за журналами на php и не вижу их. Но, опять же, дважды проверим Funk F.N: Я собираюсь включить отчет об ошибках и вернусь. Спасибо за предложение. Что касается html-формы, это форма в index.php. Файл находится в корневом файле (xampp / htdocs / myweb / index.php).
Хорошо, я дважды проверил БЕЗОПАСНОСТЬ. Это переменная типа bool, определяющая, должно ли соединение быть безопасным или нет. define ("БЕЗОПАСНЫЙ", ИСТИНА); Забавно: если я установлю значение false, все будет работать нормально.
Если я вас правильно понимаю, вы начинаете каждый файл с function sec_session_start() { ... }, но если у вас нет чего-то большего, что вы не показываете (и поэтому вам всегда следует тратить время на формирование минимальный воспроизводимый пример, поэтому, пожалуйста, сделайте это), вы на самом деле не вызов этой функции, поэтому сеанс никогда не создается.
Привет, спасибо за ваш вклад. Я отредактировал свой ответ, добавив отрывок из того, что я включаю в начало каждого файла. Я старался свести код к минимуму, может быть, даже слишком много.
Это не сложная проблема, поэтому: пожалуйста, найдите время, чтобы сделать минимальный воспроизводимый пример. Все, что вам нужно, это два файла, один из которых запускает сеанс, генерирует форму с одним скрытым вводом, установленным на известное значение и одной кнопкой отправки, с обработчиком сообщений, который устанавливает значение сеанса и перенаправляет на второй файл, и второй файл, который запускает сеанс и выполняет print_r глобальной переменной сеанса. Это легко сделать, а затем вы можете вернуться назад, добавляя все больше и больше вашего реального кода, чтобы точно определить, когда что-то начинает ломаться. Вот как вы делаете эффективную отладку.
О, я думал, вы имели в виду разместить здесь код. Извините, я неправильно понял. Я знаю, как отлаживать упрощение, основанное на принципах «разделяй и властвуй», но спасибо за предложение. Я отлаживал весь свой код, но последствия этого флага всегда не обращали внимания. Как я сказал в ответе (мне нужно подождать 2 дня, чтобы принять его), проблема была не в коде, а в конфигурации сервера, касающейся перенаправлений безопасности. В любом случае, спасибо за ваше время, очень признателен.






Проблема решена. Я все делал правильно, как они сказали, по книге. Проблема заключалась в следующем: Я установил для параметра безопасности значение ИСТИНА при настройке параметров cookie для сеанса. Это заставляет файлы cookie передаваться только через защищенные соединения (подробнее здесь session_set_cookie_params)
Проблема в том, что все заходят на сайт по www. или ничего (на самом деле http), и из-за этого файлы cookie не будут передаваться, потому что это небезопасное соединение. Но если вы используете https (или https: // www), все работает нормально (у меня на сервере установлен сертификат ssl). Решением было использовать перенаправление в файле .htacess на сервере, чтобы все было перенаправлено на https: // www для обеспечения безопасного доступа. Я использовал этот код
RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Спасибо всем за советы и предложения.
Ваше здоровье!
Взгляните на
$secure = SECURE;- строка не заключена в кавычки. Вы получаете какое-то предупреждение?