programing

PHP의 HTTP_HOST와 SERVER_NAME의 차이점은 무엇입니까?

copyandpastes 2023. 2. 1. 22:24
반응형

PHP의 HTTP_HOST와 SERVER_NAME의 차이점은 무엇입니까?

$_SERVER['HTTP_HOST'] ★★★★★★★★★★★★★★★★★」$_SERVER['SERVER_NAME']PHP ★★★★★★★★★★★★★★★★?

어떤 경우에, 그 이유는 무엇입니까?

HTTP_HOSTHTTP 요청 헤더에서 취득되며, 이는 클라이언트가 실제로 요청의 "타깃 호스트"로 사용한 것입니다.SERVER_NAME는 서버 설정에 정의되어 있습니다.어떤 것을 사용할지는 필요한 용도에 따라 달라집니다.그러나 이제 하나는 비즈니스 로직에서 사용하기에는 신뢰할 수 없는 클라이언트 제어 값이고 다른 하나는 보다 신뢰할 수 있는 서버 제어 값임을 깨달아야 합니다., 해당 웹 에 "", ""가 .SERVER_NAME올바르게 설정되어 있습니다.Apache HTTPD를 예로 들어 설명서에서 발췌한 내용은 다음과 같습니다.

'아니오'의 경우ServerName이 지정되면 서버는 IP 주소에 대해 역룩업을 실행하여 호스트 이름을 추론하려고 합니다.에서 가 지정되어 ServerName그러면 서버는 착신 요구의 포트를 사용합니다.과 예측 최적으로 , 「」를 사용해 .ServerName★★★★★★ 。


업데이트: PHP가 항상 반환된다는 bobince의 답변 링크가 포함된 당신의 질문에 대한 Pekka의 답변을 확인한 후HTTP_HOST의 값 " " " " " " " "SERVER_NAME몇 년 전의 PHP 4.x + Apache HTTPD 1.2.x 경험과는 달리 Windows XP(Apache HTTPD 2.2.1 with PHP 5.2.8)의 현재 XAMPP 환경에서 약간의 먼지를 제거하고 시작한 후 Java 어플리케이션을 사용하여 생성된 두 값을 모두 인쇄하는 PHP 페이지를 만들었습니다.Host헤더와 테스트를 통해 이것이 실제로 (거의) 사실이라는 것을 알게 되었습니다.

처음에 PHP를 의심하고 주제에 관한 PHP 버그 보고서를 파헤친 후 문제의 근원이 사용된 웹 서버에 있다는 것을 알게 되었습니다.HTTP를 잘못 반환했습니다.Host(헤더)를 합니다.SERVER_NAME가 요구되었습니다.그래서 Apache HTTPD 버그 리포트를 주제에 관한 다양한 키워드를 사용하여 조사했는데, 마침내 관련된 버그를 발견했습니다.이 동작은 Apache HTTPD 1.3 전후로 도입되었습니다.지시문을 다음과 같이 설정해야 합니다.on <VirtualHost>ServerNamehttpd.conf(또한 문서 하단의 경고를 확인합니다!)

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

이건 나한테 효과가 있었어.

약,,SERVER_NAME신뢰성은 높지만 서버 구성에 의존합니다.

HTTP_HOST할 수 있습니다.이치노HTTP_HOST의 의 값www.stackoverflow.com.

SERVER_NAME「」로부터 됩니다.VirtualHost더 신뢰할 수 있는 것으로 간주됩니다.다만, Web 서버의 셋업 방법에 관한 특정의 조건하에서 외부에서 조작할 수도 있습니다.이 질문은, 양쪽의 변형의 시큐러티 측면에 대해 설명합니다.

어느 쪽도 안전하다고 기대해서는 안 된다.그렇지만 무엇을 사용할지는 무엇을 하고 싶은지에 따라 다릅니다.되고 있는 하려면 , 「 」를 할 수 .HTTP_HOST악의적인 사용자가 보낸 잘못된 값이 아무것도 손상시키지 않는 한.

답변에서 설명한 바와 같이 서버가 80 이외의 포트(개발/인트라넷머신에서 흔히 볼 수 있는 포트)에서 동작하는 경우HTTP_HOST포토를 하고 있습니다만, 「 」는 「 」입니다.SERVER_NAME지지않않않않

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(적어도 Apache 포트 기반 가상 호스트에서는 이 점을 알 수 있습니다.)

:HTTP_HOST포함하지 않음:443HTTPS에서 실행하는 경우(테스트하지 않은 비표준 포트에서 실행하는 경우는 제외).

다른 유저도 지적했듯이, IPv6 를 사용하는 경우는, 다음의 2 개도 다릅니다.

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'

를 사용하는 는, IPv6 를 사용하는 .HTTP_HOSTSERVER_NAME라고 했을 경우.http://[::1]/츠키다

HTTP_HOST = [::1]
SERVER_NAME = ::1

즉, 예를 들어 mod_rewrite를 실행하면 좋지 않은 결과가 발생할 수 있습니다.SSL 리다이렉트의 예:

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

이것은, 호스트명 없이 서버에 액세스 하고 있는 경우에만 적용됩니다.

서버를 통해 확인하려는 경우.php 또는 그 외의 것을 사용하고 싶은 경우는, 다음과 같이 호출합니다.

<?php
    phpinfo(INFO_VARIABLES);
?>

또는

<?php
    header("Content-type: text/plain");

    print_r($_SERVER);
?>

그런 다음 사이트에 대한 모든 유효한 URL을 사용하여 액세스하고 차이를 확인하십시오.

내가 뭘 알고 싶은지에 따라 다르죠SERVER_NAME은 서버의 호스트 이름입니다.HTTP_HOST는 클라이언트가 접속한 가상 호스트입니다.

'무슨 뜻인지'가 무슨 하는 데 이 좀 걸렸어요.SERVER_NAME더 신뢰할 수 있습니다.공유 서버를 사용하고 있으며 가상 호스트 디렉티브에 액세스할 수 없습니다.는 mod_rewrite에서 사용합니다..htaccess 지도를 만들다HTTP_HOST하다in면면면 in in in면 면 in in in in in in in.HTTP_HOST미가있있 있있있다다

의 가상 「」를 사용하고 있는 .ServerName가상 호스트내의 디렉티브는, 이 가상 호스트에 매핑 되는 호스트명을 간단하게 나타냅니다.은, 되는 호스트명( 「」, 「」, 「」, 「」, 「」)입니다.HTTP_HOST 자체는 있습니다).「 」 「 」 「 」 「 」 。서버명 자체는 디렉토리에 매핑 됩니다.매핑이 가상 호스트 지시와 htaccess mod_rewrite 규칙에 따라 수행되는지 여부는 여기서 두 번째입니다. 경우, 「 」HTTP_HOST 하면 '아까보다'와 거예요.SERVER_NAME아파치

그러나 IP 기반 가상 호스트에서는 상황이 다릅니다. 이 경우만, 이 경우만, 다른 경우도 있습니다.이것은, 클라이언트가 서버가 이름이 아닌 IP 에 의해서 선택되기 때문입니다.실제로 이것이 중요한 특수한 구성이 있을 수 있습니다.

그래서 지금부터 제가 사용하는 것은SERVER_NAME이 특별한 구성으로 코드가 이식될 경우를 대비해서 입니다.

$_SERVER['SERVER_NAME']는 웹 서버 구성에 기반합니다.$_SERVER[``HTTP_HOST']는 클라이언트로부터의 요구를 기반으로 합니다.

간단한 셋업(CentOS 7, Apache 2.4.x 및 PHP 5.6.20)과 하나의 웹 사이트(가상 호스팅을 가정하지 않음)가 있다고 가정하면...

PHP의 의미에서는,$_SERVER['SERVER_NAME']PHP가 에 등록하는 요소입니다.$_SERVERApache 구성에 따라 superglobal(**ServerName**로 지시하는.UseCanonicalName Onhttpd.conf(포함된 가상 호스트컨피규레이션파일 등)의 경우 HTTP_HOST는 HTTP에서 파생됩니다.hostheader를 클릭합니다.이것을 유저 입력으로 취급합니다.사용하기 전에 필터링 및 검증합니다.

다음은 제가 사용하는 장소의 예입니다.$_SERVER['SERVER_NAME']비교의 근거로 삼다.다음 방법은 제가 만든 콘크리트 아이 클래스입니다.ServerValidator(의 아이Validator).ServerValidator는 사용하기 전에 $_SERVER 내의 6개 또는7개의 요소를 체크합니다.

HTTP 요구가 POST인지 아닌지를 판단할 때는 이 방법을 사용합니다.

public function isPOST()
{
    return (($this->requestMethod === 'POST')    &&  // Ignore
            $this->hasTokenTimeLeft()            &&  // Ignore
            $this->hasSameGETandPOSTIdentities() &&  // Ingore
            ($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')));
}

이 메서드가 호출될 때까지 관련된 $_SERVER 요소의 모든 필터링 및 검증이 수행되었을 것입니다(및 관련 속성 세트).

라인이...

($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')

...이 체크는$_SERVER['HTTP_HOST']값(최종적으로 요청된 값에서 파생됨)hostHTTP 헤더)의 일치$_SERVER['SERVER_NAME'].

지금, 나는 나의 예를 설명하기 위해 초글로벌 스피크를 사용하고 있지만, 그것은 단지 몇몇 사람들이 익숙하지 않기 때문이다.INPUT_GET,INPUT_POST,그리고.INPUT_SERVER에 대해서

결론은 4가지 조건이 모두 충족되지 않는 한 서버에서 POST 요구를 처리하지 않는다는 것입니다.따라서 POST 요구의 관점에서 HTTP를 제공하지 못했습니다.hostheader(이전의 존재 테스트 완료)는 엄밀한 HTTP 1.0 브라우저에서는 doom을 의미합니다.또한 요청된 호스트httpd.conf값과 일치해야 하며 확장으로 인해$_SERVER('SERVER_NAME')에서$_SERVER초글로벌의다시 한 번 말씀드리지만INPUT_SERVERPHP 필터 기능이 있지만, 내 말뜻을 알잖아요.

Apache가 자주 사용하는 것은ServerName표준 리다이렉트(URL의 후행 슬래시를 생략한 경우 등).를 들어 URL 개서를 사용하지 않아도 http://www.example.com이 http://www.example.com/),이 됩니다.

사용하고 있다$_SERVER['SERVER_NAME']표준으로서가 아니라$_SERVER['HTTP_HOST']이 문제에 대해서는 여러 가지 의견이 분분하다. $_SERVER['HTTP_HOST']공백일 수 있으므로 위의 공개 메서드와 같은 코드 규약을 작성하기 위한 기초가 되어서는 안 됩니다.그러나 둘 다 설정될 수 있다고 해서 동등하다는 보장은 없습니다.테스트를 통해 확실하게 알 수 있습니다(Apache 버전과 PHP 버전을 염두에 두고).

balusC가 SERVER_NAME은 신뢰할 수 없으며 Apache config, 서버 이름 구성, 사용자와 서버 사이에 있을 수 있는 방화벽에서 변경할 수 있습니다.

다음 함수는 항상 포트 없이 실제 호스트(사용자 유형 호스트)를 반환하며 거의 안정적입니다.

function getRealHost(){
   list($realHost,)=explode(':',$_SERVER['HTTP_HOST']);
   return $realHost;
}

언급URL : https://stackoverflow.com/questions/2297403/what-is-the-difference-between-http-host-and-server-name-in-php

반응형