PHP сессия HTTP для HTTPS проблема - PullRequest
12 голосов
/ 07 мая 2011

У меня есть страница (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");
}

Мой файл php.iniнастройки cookie

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

Ответы [ 2 ]

9 голосов
/ 08 мая 2011

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

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

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

7 голосов
/ 08 мая 2011

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

Как ответ на Сеанс потерян при переключении с 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. Безопасные куки будут сохранены, когда вы сделаете это.


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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...