Подтвердить что ты не робот

Проблема PHP с HTTP-протоколом HTTPS

У меня есть страница (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
4b9b3361

Ответ 1

Ответил, чтобы помочь людям, которые могут споткнуться об этом

Как ответ на Сессия, потерянная при переключении с 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-запрос к их партнеру HTTPS с помощью parse_url и http_build_url.


Второе альтернативное решение

Если вы действительно не хотите использовать HTTPS для всего, то не session_start() на страницах, к которым обращается HTTP. Безопасные файлы cookie будут сохранены, когда вы это сделаете.


Третье альтернативное решение

Другим решением является попытка обнаружения пользователя по IP-адресам и пользовательскому агенту. Это не гарантирует точность, поэтому я предлагаю использовать HTTPS только для всего. Например, Paypal всегда использует HTTPS даже для мирских статических страниц.

Ответ 2

Описание @rickchristie - это хорошо, но я думаю, что там лучшее решение, которое он не предлагает. Если вы не всегда хотите использовать HTTPS (что иногда имеет смысл: страница about_us не должна быть безопасной), вы можете следовать рекомендациям session_start и используйте названные сеансы, чтобы продолжить предыдущий сеанс. Это прост в использовании; просто включите вызовы session_start с помощью

session_name("MySession"); // replace with whatever makes sense
session_start();

на всех защищенных страницах.