У меня есть страница (HTTPS) login.php, которая остается HTTPS (т.е. после входа пользователя в учетную запись). Теперь проблема заключается в том, что пользователь во время входа в защищенную панель управления нажимает на нечувствительную страницу, например (HTTP) about-us.php, сеанс не передается по HTTP, поскольку у меня есть session.cookie_secure = 1, что означает пользователь появляется на страницах HTTP.
Однако, когда пользователь возвращается на страницу панели мониторинга или на любую страницу конфиденциальной учетной записи, мне сказали, что он все равно должен войти в систему (т. Е. От HTTP до HTTPS)? Однако это не так, и он также выходит из протокола HTTPS-соединения тоже?
Я считаю, что мне не хватает чего-то, что вызывает эту проблему. Вот мой код:
Это файл заголовка PHP, который вызывается для запуска сеанса на странице login.php:
session_start(); session_regenerate_id(true); /*avoid session fixation attempt*/ /*Create and check how long session has been started (over 5 mins) regenerate id - avoid session hijack*/ if(!isset($_SESSION['CREATED'])) { $_SESSION['CREATED'] = time();/*time created session, ie from login/contact advertiser/email_confirm only ways for new session to start*/ } elseif(time() - $_SESSION['CREATED'] > 300) { /*session started more than 5 mins(300 secs) ago*/ session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/ $_SESSION['CREATED'] = time(); /*update creation time*/ } /*Check if user is logged in*/ if(!isset($_SESSION['loggedin'])) { $_SESSION['loggedin']=1;/*used to track if user is logged in on pages*/ } /*if return false browser supports standard ob_start();*/ if(ob_start("ob_gzhandler")){ob_start();}
Это файл заголовка PHP, который требуется на каждой странице, чтобы проверить, запущен ли сеанс:
session_start(); $session_errors=0;/* if>0 user not logged in*/ /*check if session is already initiated*/ if(isset($_SESSION['CREATED'])) { if(time() - $_SESSION['CREATED'] > 300) { /*session started more than 5 mins(300 secs) ago*/ session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/ $_SESSION['CREATED'] = time(); /*update creation time*/ } } elseif(!isset($_SESSION['CREATED'])){$session_errors++;}/*user not logged in*/ /*Check if user is logged in*/ if(!isset($_SESSION['loggedin'])){$session_errors++;}/*user not logged in*/ if(ob_start("ob_gzhandler")){ob_start();}
Также, если это используется, это код для включения HTTPS на нечувствительных страницах, например about-us.php
if ($_SERVER['SERVER_PORT']!=80) { $url = "http://". $_SERVER['SERVER_NAME'] . ":80".$_SERVER['REQUEST_URI']; header("Location: $url"); }
Мои настройки файлов cookie php.ini
session.cookie_secure=1 session.cookie_httponly=1 session.use_only_cookies=1 session.cookie_lifetime = 0 session.save_path = /tmp session.save_handler = files
Ответил, чтобы помочь людям, которые могут споткнуться об этом
Поскольку ответ на сеанс потерялся при переходе с HTTP на HTTPS в PHP , поскольку вы используете session.cookie_secure = 1
cookie, содержащий идентификатор сеанса, не передается, когда соединение переключается с HTTPS на HTTP. При HTTP-подключении, когда вы session_start()
, PHP создает новый идентификатор сеанса, который заменяет предыдущий идентификатор сеанса.
Ответ также предлагает решение, передает идентификатор сеанса с помощью строки запроса, который затем выбирается страницей. Это пахнет недостатком безопасности. Не забывайте, почему мы использовали HTTPS в первую очередь!
Поэтому решение, которое я вам предлагаю, заключается в том, что вы перенаправляете весь HTTP-запрос на https-копии . Используйте HTTPS для всего, что есть на вашем сайте, от css, изображений, до мирских статических html-страниц. Это действительно то, что делает каждое приложение, которое серьезно относится к безопасности. Например, при переходе на страницу github с использованием HTTP:
HTTP/1.1 301 Moved Permanently Server: nginx/0.7.67 Date: Sun, 08 May 2011 15:43:01 GMT Content-Type: text/html Content-Length: 185 Connection: close Location: https://github.com/ <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/0.7.67</center> </body> </html>
Помните, почему вы использовали HTTPS в первую очередь, если хотите быть абсолютно безопасным, используйте HTTPS для всего.
Обнаружение, если запрос HTTPS или нет (см. Этот вопрос) в бутстрапе.
Если запрос HTTP, либо перенаправить все запросы на домашнюю страницу HTTPS, либо вы можете попробовать разбор $_SERVER['REQUEST_URI']
и перенаправление HTTP-запроса своему parse_url
HTTPS с использованием parse_url
и http_build_url
.
Второе альтернативное решение
Если вы действительно не хотите использовать HTTPS для всего, то не делайте session_start()
на страницах, к которым обращается HTTP. Безопасные файлы cookie будут сохранены, когда вы это сделаете.
Третье альтернативное решение
Другое решение – попытаться обнаружить пользователя по IP-адресам и пользовательскому агенту. Это не гарантирует точность, поэтому я предлагаю использовать HTTPS только для всего. Например, Paypal всегда использует HTTPS даже для мирских статических страниц.
Описание @rickchristie – это хорошо, но я думаю, что есть лучшее решение, которое он не предлагает. Если вы не всегда хотите использовать HTTPS (что иногда имеет смысл: страница about_us не должна быть безопасной), вы можете следовать советам на странице session_start
и использовать именованные сеансы для продолжения предыдущего сеанса. Это прост в использовании; просто session_start
вызовы session_start
с
session_name("MySession"); // replace with whatever makes sense session_start();
на всех защищенных страницах.