Apa perbedaan antara HTTP_HOST
dan SERVER_NAME
dalam PHP?
dimana:
HTTP_POST
===$_SERVER['HTTP_HOST']
SERVER_NAME
===$_SERVER['SERVER_NAME']
Kapan Anda akan mempertimbangkan untuk menggunakan salah satunya dan mengapa?
php
apache
server-variables
Emanuil Rusev
sumber
sumber
HTTP_HOST
. Kalau tidak, seorang penyerang dapat memasukkan nilai apa pun dalamHost:
permintaan HTTP dan membuat server menerimanya.$_SERVER['HTTP_HOST']
atau$_SERVER['SERVER_NAME']
Jawaban:
Ini
HTTP_HOST
diperoleh dari tajuk permintaan HTTP dan inilah yang sebenarnya digunakan klien sebagai "host target" dari permintaan. TheSERVER_NAME
didefinisikan dalam konfigurasi server. Yang mana untuk digunakan tergantung pada apa yang Anda butuhkan. Namun Anda sekarang harus menyadari bahwa yang satu adalah nilai yang dikendalikan klien yang mungkin tidak dapat diandalkan untuk digunakan dalam logika bisnis dan yang lainnya adalah nilai yang dikendalikan server yang lebih dapat diandalkan. Namun Anda perlu memastikan bahwa server web yang bersangkutan memilikiSERVER_NAME
konfigurasi yang benar. Mengambil Apache HTTPD sebagai contoh, inilah kutipan dari dokumentasinya :Pembaruan : setelah memeriksa jawaban Pekka pada pertanyaan Anda yang berisi tautan ke jawaban bobince bahwa PHP akan selalu mengembalikan
HTTP_HOST
nilaiSERVER_NAME
, yang bertentangan dengan pengalaman PHP saya sendiri 4.x + Apache HTTPD 1.2.x dari beberapa tahun yang lalu , Saya meniup debu dari lingkungan XAMPP saya saat ini di Windows XP (Apache HTTPD 2.2.1 dengan PHP 5.2.8), memulainya, membuat halaman PHP yang mencetak kedua nilai, membuat aplikasi uji Java menggunakanURLConnection
untuk memodifikasiHost
header dan tes mengajari saya bahwa ini memang (salah).Setelah pertama kali mencurigai PHP dan menggali dalam beberapa laporan bug PHP tentang subjek, saya mengetahui bahwa akar masalahnya ada di server web yang digunakan, bahwa itu salah mengembalikan HTTP
Host
header ketikaSERVER_NAME
diminta. Jadi saya menggali laporan bug HTTPD Apache menggunakan berbagai kata kunci mengenai subjek dan akhirnya saya menemukan bug terkait . Perilaku ini diperkenalkan sejak sekitar Apache HTTPD 1.3. Anda perlu setUseCanonicalName
direktif untukon
di<VirtualHost>
masuknyaServerName
dihttpd.conf
(juga memeriksa peringatan di bagian bawah dokumen !).Ini berhasil untuk saya.
Ringkasnya,
SERVER_NAME
lebih dapat diandalkan, tetapi Anda bergantung pada konfigurasi server!sumber
server_name
arahan. Apalagi jika tidakserver_name
diatur juga_SERVER["SERVER_NAME"]
akan kosong.HTTP_HOST
adalah host target yang dikirim oleh klien. Itu dapat dimanipulasi secara bebas oleh pengguna. Tidak masalah untuk mengirim permintaan ke situs Anda memintaHTTP_HOST
nilaiwww.stackoverflow.com
.SERVER_NAME
berasal dariVirtualHost
definisi server dan karenanya dianggap lebih dapat diandalkan. Namun, itu juga dapat dimanipulasi dari luar dalam kondisi tertentu yang terkait dengan bagaimana server web Anda diatur: Lihat ini Pertanyaan SO ini yang berkaitan dengan aspek keamanan dari kedua variasi.Anda tidak harus bergantung pada keduanya untuk aman. Yang mengatakan, apa yang harus digunakan sangat tergantung pada apa yang ingin Anda lakukan. Jika Anda ingin menentukan domain yang digunakan skrip Anda, Anda dapat menggunakan dengan aman
HTTP_HOST
selama nilai tidak valid yang berasal dari pengguna jahat tidak dapat merusak apa pun.sumber
UseCanonicalName on
di httpd.conf untuk memaksaSERVER_NAME
menjadi nama server yang sebenarnya.$_SERVER['SERVER_NAME']
tidak akan berfungsi juga . Server yang dikonfigurasi dengan buruk akan ditetapkan$_SERVER['SERVER_NAME']
berdasarkan nilaiHost:
permintaan klien . Keduanya sama.Seperti yang saya sebutkan dalam jawaban ini , jika server berjalan pada port selain 80 (seperti yang umum pada mesin pengembangan / intranet) maka
HTTP_HOST
berisi port, sementaraSERVER_NAME
tidak.(Setidaknya itulah yang saya perhatikan di virtualhosts berbasis port Apache)
Perhatikan bahwa
HTTP_HOST
tidak tidak mengandung:443
ketika berjalan di HTTPS (kecuali jika Anda berjalan pada port non-standar, yang saya belum diuji).Seperti yang telah dicatat orang lain, keduanya juga berbeda ketika menggunakan IPv6:
sumber
Harap dicatat bahwa jika Anda ingin menggunakan IPv6, Anda mungkin ingin menggunakan
HTTP_HOST
daripadaSERVER_NAME
. Jika Anda memasukkanhttp://[::1]/
variabel lingkungan akan menjadi sebagai berikut:Ini berarti, bahwa jika Anda melakukan mod_rewrite misalnya, Anda mungkin mendapatkan hasil yang buruk. Contoh untuk pengalihan SSL:
Ini HANYA berlaku jika Anda mengakses server tanpa nama host.
sumber
https://%{SERVER_NAME}%{REQUEST_URI}
Jika Anda ingin memeriksa melalui server.php atau apa pun, Anda ingin menyebutnya dengan yang berikut:
atau
Kemudian akses dengan semua URL yang valid untuk situs Anda dan periksa perbedaannya.
sumber
Tergantung apa yang ingin saya ketahui. SERVER_NAME adalah nama host dari server, sementara HTTP_HOST adalah host virtual yang terhubung dengan klien.
sumber
SERVER_NAME
biasanya nama VirtualHost, bukan server itu sendiri. Dan di Apache,SERVER_NAME
sering diisi dengan nilai yang sama denganHTTP_HOST
(lihat jawaban BalusC).SERVER_NAME
berlaku untuk host virtual. Namun, seseorang masih dapat menggunakan pengaturan host virtual untuk satu situs. Banyak orang menggunakan hosting bersama, jadi saya mengerti maksud Anda.Perlu beberapa saat bagi saya untuk memahami apa yang dimaksud orang dengan '
SERVER_NAME
lebih dapat diandalkan'. Saya menggunakan server bersama dan tidak memiliki akses ke arahan host virtual. Jadi, saya menggunakan mod_rewrite.htaccess
untuk memetakan yang berbedaHTTP_HOST
ke direktori yang berbeda. Dalam hal ini, ituHTTP_HOST
yang bermakna.Situasi serupa jika seseorang menggunakan host virtual berbasis nama:
ServerName
arahan dalam host virtual hanya mengatakan nama host yang akan dipetakan ke host virtual ini. Intinya adalah bahwa, dalam kedua kasus, nama host yang disediakan oleh klien selama permintaan (HTTP_HOST
), harus dicocokkan dengan nama di dalam server, yang dengan sendirinya dipetakan ke direktori. Apakah pemetaan dilakukan dengan arahan host virtual atau dengan aturan mod_rewrite htaccess adalah sekunder di sini. Dalam kasus ini,HTTP_HOST
akan sama denganSERVER_NAME
. Saya senang bahwa Apache dikonfigurasi dengan cara itu.Namun, situasinya berbeda dengan host virtual berbasis IP. Dalam hal ini dan hanya dalam kasus ini,
SERVER_NAME
danHTTP_HOST
dapat berbeda, karena sekarang klien memilih server dengan IP, bukan dengan namanya. Memang, mungkin ada konfigurasi khusus di mana ini penting.Jadi, mulai dari sekarang, saya akan menggunakan
SERVER_NAME
, kalau-kalau kode saya porting dalam konfigurasi khusus ini.sumber
Dengan asumsi seseorang memiliki pengaturan yang sederhana (CentOS 7, Apache 2.4.x, dan PHP 5.6.20) dan hanya satu situs web (tidak menggunakan hosting virtual) ...
Dalam pengertian PHP,
$_SERVER['SERVER_NAME']
adalah elemen register PHP di$_SERVER
superglobal berdasarkan pada konfigurasi Apache Anda (**ServerName**
direktif denganUseCanonicalName On
) di httpd.conf (baik itu dari file konfigurasi host virtual yang disertakan, apa pun, dll ...). HTTP_HOST diturunkan darihost
header HTTP . Perlakukan ini sebagai input pengguna. Saring dan validasi sebelum menggunakan.Berikut adalah contoh tempat saya menggunakan
$_SERVER['SERVER_NAME']
sebagai dasar untuk perbandingan. Metode berikut ini dari kelas anak beton yang saya buat bernamaServerValidator
(child ofValidator
).ServerValidator
memeriksa enam atau tujuh elemen dalam $ _SERVER sebelum menggunakannya.Dalam menentukan apakah permintaan HTTP adalah POST, saya menggunakan metode ini.
Pada saat metode ini dipanggil, semua pemfilteran dan validasi elemen $ _SERVER yang relevan akan terjadi (dan set properti yang relevan).
Garis ...
... memeriksa apakah
$_SERVER['HTTP_HOST']
nilainya (akhirnya berasal darihost
tajuk HTTP yang diminta ) cocok$_SERVER['SERVER_NAME']
.Sekarang, saya menggunakan berbicara superglobal untuk menjelaskan contoh saya, tapi itu hanya karena beberapa orang tidak terbiasa dengan
INPUT_GET
,INPUT_POST
, danINPUT_SERVER
dalam halfilter_input_array()
.Intinya adalah, saya tidak menangani permintaan POST pada server saya kecuali semua empat kondisi terpenuhi. Oleh karena itu, dalam hal permintaan POST, kegagalan untuk menyediakan
host
header HTTP (keberadaan diuji sebelumnya) mantra malapetaka untuk browser HTTP 1.0 yang ketat . Selain itu, tuan rumah yang diminta harus sesuai nilai untukServerName
di httpd.conf , dan, dengan extention, nilai untuk$_SERVER('SERVER_NAME')
di$_SERVER
superglobal. Sekali lagi, saya akan menggunakanINPUT_SERVER
dengan fungsi filter PHP, tetapi Anda tahu maksud saya.Perlu diingat bahwa Apache sering menggunakan
ServerName
di pengalihan standar (seperti meninggalkan garis miring off URL: Contoh, http://www.foo.com menjadi http://www.foo.com/ ), bahkan jika Anda tidak menggunakan penulisan ulang URL.Saya menggunakan
$_SERVER['SERVER_NAME']
sebagai standar, bukan$_SERVER['HTTP_HOST']
. Ada banyak bolak-balik tentang masalah ini.$_SERVER['HTTP_HOST']
mungkin kosong, jadi ini seharusnya tidak menjadi dasar untuk membuat konvensi kode seperti metode publik saya di atas. Tapi, hanya karena keduanya dapat diatur tidak menjamin mereka akan sama. Pengujian adalah cara terbaik untuk mengetahui dengan pasti (mengingat versi Apache dan versi PHP).sumber
Seperti yang dikatakan balusC SERVER_NAME tidak dapat diandalkan dan dapat diubah di konfigurasi apache, konfigurasi nama server dari server dan firewall yang dapat berada di antara Anda dan server.
Fungsi berikut selalu mengembalikan host nyata (host yang diketik pengguna) tanpa port dan ini hampir dapat diandalkan:
sumber
$ _SERVER ['SERVER_NAME'] didasarkan pada konfigurasi server web Anda. $ _SERVER ['HTTP_HOST'] didasarkan pada permintaan dari klien.
sumber