it-swarm.dev

$ _SERVER없이 HTTPS를 사용하고 있는지 확인하는 방법 [ 'HTTPS']

서버가 HTTPS로 보안되어 있는지 확인하려면 $_SERVER['HTTPS']을 (를) 확인해야한다는 많은 온라인 자습서를 보았습니다. 내 문제는 내가 사용하는 일부 서버에서 $_SERVER['HTTPS']이 (가) 정의되지 않은 변수이며 오류가 발생한다는 것입니다. 확인할 수있는 다른 변수가 항상 정의되어 있습니까?

분명히하기 위해 현재이 코드를 사용하여 HTTPS 연결인지 확인하고 있습니다.

if(isset($_SERVER['HTTPS'])) {
    if ($_SERVER['HTTPS'] == "on") {
        $secure_connection = true;
    }
}
184
Tyler Carter

$_SERVER['HTTPS']이 (가) 정의되지 않은 경우에도 항상 작동해야합니다.

function isSecure() {
  return
    (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
    || $_SERVER['SERVER_PORT'] == 443;
}

이 코드는 IIS와 호환됩니다.

PHP.net 설명서 및 사용자 의견 에서 :

1) 스크립트가 HTTPS 프로토콜을 통해 쿼리 된 경우 비어 있지 않은 값으로 설정하십시오.

2) IIS에서 ISAPI를 사용할 때 HTTPS 프로토콜을 통해 요청하지 않은 경우 값이 "off"가됩니다. PHP를 Fast-CGI 응용 프로그램으로 실행하는 IIS7에 대해 동일한 동작이보고되었습니다.

또한 Apache 1.x 서버 (및 손상된 설치)에는 안전하게 연결하더라도 $_SERVER['HTTPS']이 (가) 정의되어 있지 않을 수 있습니다. 보장되지는 않지만 포트 443의 연결은 보안 소켓 을 사용하여 통합 에 의해 추가 포트 확인이 이루어집니다.

267
Gras Double

내 솔루션 (표준 조건 [$ _SERVER [ 'HTTPS'] == 'on']이로드 밸런서 뒤에있는 서버에서 작동하지 않기 때문에)은 다음과 같습니다.

$isSecure = false;
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
    $isSecure = true;
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') {
    $isSecure = true;
}
$REQUEST_PROTOCOL = $isSecure ? 'https' : 'http';

HTTP_X_FORWARDED_PROTO : 리버스 프록시 (로드 밸런서)가 HTTP를 사용하여 웹 서버와 통신 할 수 있으므로 HTTP 요청의 원래 프로토콜을 식별하기위한 실제 표준 리버스 프록시에 대한 요청이 HTTPS 인 경우에도 http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Common_non-standard_request_headers

110
temuraru

PHP 설명서에 따라 Chacha : "HTTPS 프로토콜을 통해 스크립트를 쿼리 한 경우 비어 있지 않은 값으로 설정하십시오." 따라서 HTTPS가 실제로 많은 경우 if 문이 false를 반환합니다. $_SERVER['HTTPS']이 (가) 있고 비어 있지 않은지 확인하고 싶을 것입니다. 특정 서버에 대해 HTTPS가 올바르게 설정되지 않은 경우 $_SERVER['SERVER_PORT'] == 443인지 확인할 수 있습니다.

그러나 일부 서버는 $_SERVER['HTTPS']도 비어 있지 않은 값으로 설정하므로이 변수도 확인하십시오.

참조 : $_SERVER$HTTP_SERVER_VARS [더 이상 사용되지 않음]에 대한 설명서

81
hobodave

$_SERVER['HTTPS']이 (가) 정의되지 않은 경우에도 작동합니다

if( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 ){
    //enable secure connection
}
14
Thamaraiselvam

Apache mod_ssl을 사용하여 서버를 실행하는 데 문제가 있었지만 phpinfo () 및 var_dump ($ _SERVER)는 PHP이 여전히 포트 80에 있다고 생각합니다.

다음은 동일한 문제가있는 사람을위한 해결 방법입니다 ....

<VirtualHost *:443>
  SetEnv HTTPS on
  DocumentRoot /var/www/vhost/scratch/content
  ServerName scratch.example.com
</VirtualHost>

주목할만한 줄은 SetEnv 줄입니다. 이를 사용하고 다시 시작한 후에는 항상 꿈꿔 왔던 HTTPS 환경 변수가 있어야합니다

9
thomas-peter

모든 이전 게시물을 읽지 않고 내 기능 만들기 :

public static function isHttps()
{
    if (array_key_exists("HTTPS", $_SERVER) && 'on' === $_SERVER["HTTPS"]) {
        return true;
    }
    if (array_key_exists("SERVER_PORT", $_SERVER) && 443 === (int)$_SERVER["SERVER_PORT"]) {
        return true;
    }
    if (array_key_exists("HTTP_X_FORWARDED_SSL", $_SERVER) && 'on' === $_SERVER["HTTP_X_FORWARDED_SSL"]) {
        return true;
    }
    if (array_key_exists("HTTP_X_FORWARDED_PROTO", $_SERVER) && 'https' === $_SERVER["HTTP_X_FORWARDED_PROTO"]) {
        return true;
    }
    return false;
}
7
ling

Apache를 사용하는 경우 항상 신뢰할 수 있습니다

$_SERVER["REQUEST_SCHEME"]

요청 된 URL의 체계를 확인합니다. 그러나 다른 답변에서 언급했듯이 SSL이 실제로 사용되고 있다고 가정하기 전에 다른 매개 변수를 확인하는 것이 좋습니다.

7
Ed de Almeida

REAL 답변 : [config] 스크립트에 복사하여 붙여 넣기 준비

/* configuration settings; X=edit may 10th '11 */
$pv_sslport=443; /* for it might be different, as also Gabriel Sosa stated */
$pv_serverport=80; /* X */
$pv_servername="mysite.com"; /* X */

/* X appended after correction by Michael Kopinsky */
if(!isset($_SERVER["SERVER_NAME"]) || !$_SERVER["SERVER_NAME"]) {
    if(!isset($_ENV["SERVER_NAME"])) {
        getenv("SERVER_NAME");
        // Set to env server_name
        $_SERVER["SERVER_NAME"]=$_ENV["SERVER_NAME"];
    }
}
if(!$_SERVER["SERVER_NAME"]) (
    /* X server name still empty? ... you might set $_SERVER["SERVER_NAME"]=$pv_servername; */
}

if(!isset($_SERVER["SERVER_PORT"]) || !$_SERVER["SERVER_PORT"]) {
    if(!isset($_ENV["SERVER_PORT"])) {
        getenv("SERVER_PORT");
        $_SERVER["SERVER_PORT"]=$_ENV["SERVER_PORT"];
    }
}
if(!$_SERVER["SERVER_PORT"]) (
    /* X server port still empty? ... you might set $_SERVER["SERVER_PORT"]=$pv_serverport; */
}

$pv_URIprotocol = isset($_SERVER["HTTPS"]) ? (($_SERVER["HTTPS"]==="on" || $_SERVER["HTTPS"]===1 || $_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://") :  (($_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://");

$pv_URIprotocol이 (가) 올 바르고 사용할 준비가되었습니다. 예 $site=$pv_URIprotocol.$_SERVER["SERVER_NAME"]. 당연히 문자열을 TRUE 및 FALSE로 바꿀 수도 있습니다. PV는 PortalPress Variable의 약자로, 항상 작동하는 직접 복사 붙여 넣기입니다. 이 조각은 프로덕션 스크립트에서 사용할 수 있습니다.

이러한 매개 변수도 수용 가능하며 웹 서버를 전환 할 때 오 탐지가 없을 가능성이 높습니다.

  1. $ _SERVER [ 'HTTPS_KEYSIZE']
  2. $ _SERVER [ 'HTTPS_SECRETKEYSIZE']
  3. $ _SERVER [ 'HTTPS_SERVER_ISSUER']
  4. $ _SERVER [ 'HTTPS_SERVER_SUBJECT']

    if($_SERVER['HTTPS_KEYSIZE'] != NULL){/*do foobar*/}
    
3
Werezywolf

내가 사용하는 가장 짧은 방법 :

$secure_connection = !empty($_SERVER['HTTPS']);

Https가 사용되면 $ secure_connection이 true입니다.

3
Markus Zeller

신뢰할 수있는 유일한 방법은 Igor M이 설명한 방법입니다.

$pv_URIprotocol = isset($_SERVER["HTTPS"]) ? (($_SERVER["HTTPS"]==="on" || $_SERVER["HTTPS"]===1 || $_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://") :  (($_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://");

다음을 고려하십시오 : 기본적으로 fastcgi와 함께 nginx를 사용하고 있습니다 (기본적으로 debian, ubuntu) fastgi_params contains 지시문 :

fastcgi_param HTTPS $ https;

sSL을 사용하지 않으면 0이 아닌 'off'가 아닌 빈 값으로 변환되어 파산됩니다.

http://unpec.blogspot.cz/2013/01/nette-nginx-php-fpm-redirect.html

3
Galvani

포트를 추가하는 것이 좋은 생각이라고 생각하지 않습니다. 특히 빌드가 다른 서버가 많을 때 특히 그렇습니다. 변경해야 할 사항이 하나 더 추가됩니다. 문서를 보면 카이저의 마지막 줄이 꽤 좋다고 생각합니다.

if(!empty($_SERVER["HTTPS"]))
  if($_SERVER["HTTPS"]!=="off")
    return 1; //https
  else
    return 0; //http
else
  return 0; //http

완벽하게 보입니다.

3
sp3c1

SSL이 일반적으로 포트 443에서 실행됨에 따라 $_SERVER['SERVER_PORT']을 (를) 확인할 수 있지만 이는 완벽한 방법이 아닙니다.

2
pix0r

이것에 대해서 어떻게 생각하니?

if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')
    $scheme = 'https';
else
    $scheme = 'http';
2
toni rmc

내 서버 (Ubuntu 14.10, Apache 2.4, php 5.5)에서 PHP 스크립트가 https를 통해로드되면 변수 $_SERVER['HTTPS']이 설정되지 않습니다. 나는 무엇이 잘못되었는지 모른다. 그러나 .htaccess 파일의 다음 줄이이 문제를 해결합니다.

RewriteEngine on

RewriteCond %{HTTPS} =on [NC] 
RewriteRule .* - [E=HTTPS:on,NE]
2
Karry

관심을 끌기 위해 현재 chrome 카나리아가

HTTPS : 1

서버 구성에 따라 다음을 다시 얻을 수 있음을 의미 할 수 있습니다.

HTTPS : 1, on

켜져있는 경우 테스트하고 있었기 때문에 응용 프로그램이 중단되었습니다. 현재 chrome 카나리아 만이 작업을 수행하는 것 같지만 카나리아의 항목은 일반적으로 "정상"chrome 잠시 후에 도착합니다.

1
John Smith

여기 내가 오랫동안 사용했던 재사용 가능한 기능이 있습니다. HTH.

참고 : 내 코드에서 사용자 정의 상수 인 HTTPS_PORT의 값은 환경에 따라 다를 수 있습니다 (예 : 443 또는 81).

/**
 * Determine if this is a secure HTTPS connection
 * 
 * @return  bool    True if it is a secure HTTPS connection, otherwise false.
 */
function isSSL()
{
    if (isset($_SERVER['HTTPS'])) {
        if ($_SERVER['HTTPS'] == 1) {
            return true;
        } elseif ($_SERVER['HTTPS'] == 'on') {
            return true;
        }
    } elseif ($_SERVER['SERVER_PORT'] == HTTPS_PORT) {
        return true;
    }

    return false;
}
1
crmpicco
$secure_connection = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || (!empty($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] != 'off') || $_SERVER['REQUEST_SCHEME'] == 'https' || $_SERVER['SERVER_PORT'] == 443) ? true : false;

코드가 가능한 것을 확인하고 있으며 IIS 웹 서버에서도 작동합니다. v44가 헤더 HTTP : 1을 설정하지 않았으므로 Chrome이므로 HTTP_HTTPS를 확인하는 것이 좋습니다. 이 코드가 https와 일치하지 않으면 웹 서버 또는 프록시 서버가 제대로 구성되지 않은 것입니다. Apache 자체는 HTTPS 플래그를 올바르게 설정하지만 프록시를 사용할 때 문제가 발생할 수 있습니다 (예 : nginx). nginx https 가상 호스트에서 일부 헤더를 설정해야합니다

proxy_set_header   X-HTTPS 1;

프록시에서 X-HTTPS를 찾아서 일부 Apache 모듈을 사용하여 HTTPS 플래그를 올바르게 설정하십시오. mod_fakessl, mod_rpaf 등을 검색하십시오.

1
mikep

Nginx를로드 밸런싱 시스템 검사로 사용하면 $ _SERVER [ 'HTTP_HTTPS'] == 1 ssl에 대한 다른 검사가 실패합니다.

1
basis

한 걸음 더 나아가서 연결하려는 사이트가 SSL을 지원하는지 확인할 수 있습니다 (한 프로젝트는 사용자에게 URL을 요청하고 http 또는 https 사이트에 API 팩을 설치했는지 확인해야합니다).

내가 사용하는 기능은 다음과 같습니다. 기본적으로 cURL을 통해 URL을 호출하여 https가 작동하는지 확인하십시오!

function hasSSL($url) 
{
    // take the URL down to the domain name
    $domain = parse_url($url, PHP_URL_Host);
    $ch = curl_init('https://' . $domain);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); //its a  HEAD
    curl_setopt($ch, CURLOPT_NOBODY, true);          // no body
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);  // in case of redirects
    curl_setopt($ch, CURLOPT_VERBOSE, 0); //turn on if debugging
    curl_setopt($ch, CURLOPT_HEADER, 1);     //head only wanted
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);    // we dont want to wait forever
    curl_exec($ch);
    $header = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($header === 200) {
        return true;
    }
    return false;
}

이것은 https를 사용하고 있는지 (질문과 같이) 확인하는 것뿐만 아니라 https를 사용해야 할 때 (또는 SHOULD) 확인하는 가장 신뢰할 수있는 방법입니다.

참고 : 사이트에 http 및 https 페이지가 다를 수 있습니다 (실제로는 아니지만 ...). 따라서 http를 사용하라는 메시지가 표시되면 변경할 필요가 없습니다 .. 대부분의 사이트 동일하고 아마도 자신을 다시 라우팅해야하지만이 추가 검사는 용도가 있습니다 (확실히 말하면 사용자가 사이트 정보를 입력하고 서버 측에서 확인하려는 프로젝트에서 말했듯이)

0
CFP Support

여기에서 주요 제안을 사용하고 HTTPS가 설정되지 않은 경우 로그의 "PHP Notice"에 짜증이났습니다. null-coalescing operator "??"를 사용하여 피할 수 있습니다.

if( ($_SERVER['HTTPS'] ?? 'off') == 'off' ) {
    // redirect
}

(참고 : PHP v7 이전에는 사용할 수 없습니다)

0
garafajon

이것이 내가 이것을 찾는 방법입니다.

$https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||
        !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
            strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;

return ($https) ? 'https://' : 'http://';
0
Fhulufhelo Mokhomi

확인하는 모든 것이 올바른지 확인하기 위해 전역 필터를 추가합니다.

function isSSL() {

    $https = filter_input(INPUT_SERVER, 'HTTPS');
    $port = filter_input(INPUT_SERVER, 'SERVER_PORT');
    if ($https) {

        if ($https == 1) {
            return true;
        } elseif ($https == 'on') {
            return true;
        }
    } elseif ($port == '443') {
        return true;
    }

    return false;
}
0
Rodrigo Manara

Incapsula의로드 밸런서를 사용하는 경우 IRule을 사용하여 서버의 사용자 지정 헤더를 생성해야합니다. 포트가 80으로 설정된 경우 "http"및 443과 같은 경우 "https"와 동일한 HTTP_X_FORWARDED_PROTO 헤더를 작성했습니다.

0
Nadav