PHP https проверить с помощью гибкого ssl (cloudflare), как это сделать?
Справочная информация: веб-сайт (example.com), настройка DNS через прокси-план Cloudflare, предлагает "гибкий ssl" (здесь), что означает, что ssl существует только между клиентом и облачным флагом, а не между облачным флагом и сервером, поэтому ему не нужен выделенный ip и не требуется специальных настроек на сервере. Сервер настроен на то, чтобы не использовать ssl (просто общий веб-сайт), однако cloudflare flexible ssl заботится о аспекте ssl.
Язык: PHP (codeignighter, но это действительно не имеет значения)
Цель: при просмотре в домене "exmple.com/" или "http://exmple.com/" сгенерировать переменную "http://example.com" и при просмотре на "https://example.com/*" для генерации переменной "https://example.com".
Что должно работать (но не работает):
$root = '';
if( isset($_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] != 'off' )
{
//it doesnt reach here...
$root .= 'https://';
}
else
{
$root .= 'http://';
}
$root .= "".$_SERVER['HTTP_HOST'];
$root .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);
Я всегда могу сделать так: "//example.com", но это действительно не решает проблему для меня.
Мысли? Должен ли я выполнять некоторое сравнение строк для определения https-ness?
Я уверен, что причина этого в том, что запрос достигает сервера (https или http), он поступает через порт 80, и он не распознается как ssl, поэтому $_SERVER ['HTTPS'] не определен. Я мог бы настроить пользовательский ssl между сервером и облачным флером, но был бы лучше (меньше усилий), если бы я мог просто использовать некоторое регулярное выражение и каким-то образом сравнить URL-адрес.
Я также хотел бы знать возможные проблемы и уязвимости.
Спасибо:)
Ответы
Ответ 1
Хорошо, я отвечу на свой вопрос для будущих людей, у которых есть такая же проблема:
if(!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])){
$root .= $_SERVER['HTTP_X_FORWARDED_PROTO'].'://';
}
else{
$root .= !empty($_SERVER['HTTPS']) ? "https://" : "http://";
}
Пришел к нему, когда я внимательно смотрел на $_SERVER
и искал поиск по HTTP_X_FORWARDED_PROTO
и получил меня на несколько страниц, которые подтвердили это.
Ответ 2
$_SERVER['HTTP_X_FORWARDED_PROTO']
не работает для меня. Я не знаю почему. В любом случае, здесь мое решение:
function is_https_buttflare() {
return isset($_SERVER['HTTPS']) ||
($visitor = json_decode($_SERVER['HTTP_CF_VISITOR'])) &&
$visitor->scheme == 'https';
}
Ответ 3
Он работает на меня без проблем. Вы можете использовать в любом месте:
function is_ssl_active() {
if (isset($_SERVER['HTTP_CF_VISITOR'])) {
$cf_visitor = json_decode($_SERVER['HTTP_CF_VISITOR']);
if (isset($cf_visitor->scheme) && $cf_visitor->scheme == 'https') {
return true;
}
} else if (isset($_SERVER['HTTPS'])) {
return true;
}
return false;
}
Cloudflare помещает некоторые HTTP-заголовки, такие как "CF-Visitor". Нажмите здесь, чтобы узнать больше.
Ответ 4
Я столкнулся с той же проблемой, когда я не мог получить переменную $_SERVER [ "HTTPS" ], которая появляется при выполнении var_dump ($ _ SERVER). В CloudFlare есть три параметра SSL (гибкий SSL, полный SSL и полный SSL (строгий). Для серверов с
самоподписанные сертификаты, рекомендуется использовать полный SSL. После того, как я изменил свои настройки на Full SSL, появилась переменная $_SERVER [ "HTTPS" ], а $_SERVER [ "SERVER_PORT" ] изменилась с 80 на 443. Теперь я могу проверить, является ли моя страница HTTPS или не намного проще, например это:
public function get_https_status() {
return isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on' ?
true : false;
}
До обнаружения этих изменений я полагался на $_SERVER [ "HTTP_CF_VISITOR" ] и проверял схему, все это отлично работало при доступе к странице через общедоступный IP-адрес, но при обращении к странице локально, другими словами, localhost "в качестве URL-адреса, $_SERVER [" HTTP_CF_VISITOR "] не существовало, но $_SERVER [" HTTPS "] сделал... Поэтому моя проблема заключалась в доступе к странице через общедоступный IP-адрес, $_SERVER [" HTTPS "] не отображался, а $_SERVER [ "HTTP_CF_VISITOR" ]. И наоборот.
Ответ 5
Я сделал это, чтобы проверить все результаты:
// check if ssl used on server
if ( (!empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) || $_SERVER['SERVER_PORT'] == 443 ){
echo '<script>console.log("https")</script>';
//check if ssl used on load balancers such as cloudflare
}elseif ( !empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
echo '<script>console.log("https")</script>';
}else{
echo '<script>console.log("http")</script>';
}
Ответ 6
Вы пытались проверить переменную $_SERVER ['SERVER_PORT']? Это должно вернуть "80", если это просто HTTP-соединение, или "443", если вы используете HTTPS-соединение.
Таким образом, мы надеемся, что такая функция будет работать:
function get_http()
{
if ($_SERVER['SERVER_PORT'] == '443')
{
return 'https';
}
return 'http';
}