รับโดเมนปัจจุบัน


140

ฉันมีเว็บไซต์ของฉันบนเซิร์ฟเวอร์

http://www.myserver.uk.com

สำหรับเรื่องนี้ฉันมีสองโดเมน

http://one.com

และ

http://two.com

ฉันต้องการได้รับกับโดเมนปัจจุบันของ PHP แต่ถ้าฉันใช้$_SERVER['HTTP_HOST']แล้วนี่แสดงให้ฉัน

myserver.uk.com

แทน:

one.com or two.com

ฉันจะรับโดเมนไม่ใช่ชื่อเซิร์ฟเวอร์ได้อย่างไร

ฉันมี PHP เวอร์ชัน 5.2


คุณสามารถได้รับ URl หลักเท่านั้น ตัวไหนคือตัวหลักจากสามตัวนี้
รหัส Spy

2
ว่าคำขอเปลี่ยนเส้นทาง 'โดเมนทั้งสองของคุณไปยังเซิร์ฟเวอร์ของคุณอย่างไร
xiaofeng.li

1
@infgeoax อาจจะกรอบที่ ...
CodeCaster

primary คือ myserver.uk.com ดังนั้นฉันจะได้รับชื่อโดเมนปัจจุบันได้อย่างไร ถ้าฉันเปิดไซต์ด้วยที่อยู่ one.com ฉันต้องการรับ one.com แทน myserver.uk.com
Tony Evyght

@TonyEvyght ที่ infgeoax จุดและฉันพยายามที่จะทำให้คุณควรจะ$_SERVER['HTTP_HOST']ได้รับชื่อโฮสต์ที่คุณกำลังเชื่อมต่อกับใน หากเว็บไซต์one.comและtwo.com"เปลี่ยนเส้นทาง" โดยใช้กรอบ (i) หน้าเว็บนั้นยังคงมาจาก myserver.uk.com ดังนั้นคุณจะไม่ได้รับโดเมนจริง แหล่ง HTML one.comคืออะไร
CodeCaster

คำตอบ:


175

ลองใช้สิ่งนี้: $_SERVER['SERVER_NAME']

หรือแยกวิเคราะห์

$_SERVER['REQUEST_URI']

apache_request_headers ()


23
-1: ด้วยคำตอบนี้เพียงอย่างเดียวฉันไม่ทราบแน่ชัดว่าคำแนะนำต่าง ๆ ที่ฉันกำลังทำอยู่นั้นคืออะไร แน่นอนว่าเรื่องนี้ทำให้ผมชี้ไปที่ยังคงมองจาก แต่ด้วยตัวเองนี้เป็นจริงไม่ได้เป็นคำตอบที่ดี ...
แจสเปอร์

4
เพียง print_r (apache_request_headers ()) และคุณจะเข้าใจทุก :)
OneHalf

2
@SarahLewis HTTP_X_ORIGINAL_HOSTสามารถแก้ไขได้โดยผู้ใช้และไม่สามารถเชื่อถือได้ นี่อาจไม่ใช่ปัญหาเสมอไป แต่เป็นสิ่งที่ควรระวัง
wp-overwatch.com

64

การใช้งานที่ดีที่สุดจะเป็น

echo $_SERVER['HTTP_HOST'];

และสามารถใช้ได้ดังนี้

if (strpos($_SERVER['HTTP_HOST'], 'banana.com') !== false) {
    echo "Yes this is indeed the banana.com domain";
}

รหัสด้านล่างนี้เป็นวิธีที่ดีในการดูตัวแปรทั้งหมดใน $ _SERVER ในเอาต์พุต HTML ที่มีโครงสร้างพร้อมกับคำหลักของคุณที่ไฮไลต์ซึ่งหยุดการทำงานทันทีหลังจากดำเนินการ เนื่องจากบางครั้งฉันก็ลืมที่จะใช้ตัวเอง - ฉันคิดว่านี่อาจดี

<?php
    // Change banana.com to the domain you were looking for..
    $wordToHighlight = "banana.com";
    $serverVarHighlighted = str_replace( $wordToHighlight, '<span style=\'background-color:#883399; color: #FFFFFF;\'>'. $wordToHighlight .'</span>',  $_SERVER );
    echo "<pre>";
    print_r($serverVarHighlighted);
    echo "</pre>";
    exit();
?>

39

การใช้$_SERVER['HTTP_HOST']ทำให้ฉัน (โดเมนย่อย) maindomain.extension ดูเหมือนจะเป็นทางออกที่ง่ายที่สุดสำหรับฉัน

หากคุณ 'เปลี่ยนเส้นทาง' ผ่าน iFrame จริงๆคุณสามารถเพิ่มพารามิเตอร์GETซึ่งระบุโดเมน

<iframe src="myserver.uk.com?domain=one.com"/>

จากนั้นคุณสามารถตั้งค่าตัวแปรเซสชันที่เก็บข้อมูลนี้ไว้ตลอดทั้งแอปพลิเคชันของคุณ


1
ที่สำคัญส่วนใหญ่จะมีหมายเลขพอร์ตเพื่อที่ฉันจะได้ไม่ต้องต่อกันอีกที phpinfo แนะนำโดย bsdnoobz ช่วยให้ฉันค้นหาโซลูชันที่เหมาะสมว่า

30

วิธีเดียวที่ปลอดภัยในการทำเช่นนี้

คำตอบอื่น ๆ ทั้งหมดในหน้านี้มีผลกระทบด้านความปลอดภัยที่คุณต้องระวัง

วิธีการรับประกันความปลอดภัยเพียงอย่างเดียวในการดึงข้อมูลโดเมนปัจจุบัน คือ𝓼𝓽𝓸𝓻𝓮𝓲𝓽𝓲𝓷𝓪𝓼𝓮𝓬𝓾𝓻𝓮𝓵𝓸𝓬𝓪𝓽𝓲𝓸𝓷𝔂𝓸𝓾𝓻𝓼𝓮𝓵𝓯

เฟรมเวิร์กส่วนใหญ่ดูแลการจัดเก็บโดเมนให้คุณดังนั้นคุณจะต้องการศึกษาเอกสารประกอบสำหรับเฟรมเวิร์กเฉพาะ หากคุณไม่ได้ใช้เฟรมเวิร์กให้พิจารณาจัดเก็บโดเมนในที่ต่อไปนี้:

+ ------------------------------------------------- --- + ----------------------------------- +
 | วิธีการที่ปลอดภัยในการจัดเก็บโดเมน | ใช้โดย |
+ ------------------------------------------------- --- + ----------------------------------- +
 | ไฟล์ปรับแต่ง | Joomla, Drupal / Symfony |
 | ฐานข้อมูล | WordPress |
 | ตัวแปรด้านสิ่งแวดล้อม Laravel
 | รีจิสทรีบริการ | Kubernetes DNS |
+ ------------------------------------------------- --- + ----------------------------------- +


คุณสามารถใช้สิ่งต่อไปนี้ ... แต่มันไม่ปลอดภัย

แฮกเกอร์สามารถทำให้ตัวแปรเหล่านี้แสดงผลได้ตามต้องการ สิ่งนี้สามารถนำไปสู่การวางยาพิษแคชและการโจมตีฟิชชิงที่แทบจะสังเกตไม่เห็น

$_SERVER['HTTP_HOST']

นี้ได้รับโดเมนจากส่วนหัวของคำขอที่มีการเปิดให้จัดการโดยแฮกเกอร์ เหมือนกับ:

$_SERVER['SERVER_NAME']

สิ่งนี้สามารถทำได้ดีกว่าหากการตั้งค่า Apache usecanonicalnameถูกปิด ในกรณีนี้$_SERVER['SERVER_NAME']จะไม่ได้รับอนุญาตให้เติมด้วยค่าที่กำหนดเองอีกต่อไปและจะปลอดภัย นี่คืออย่างไรก็ตามไม่ใช่ค่าเริ่มต้นและไม่ปกติของการตั้งค่า


ในระบบยอดนิยม

ด้านล่างเป็นวิธีที่คุณสามารถรับโดเมนปัจจุบันในกรอบ / ระบบต่อไปนี้:

WordPress

$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

หากคุณกำลังสร้าง URL ใน WordPress เพียงใช้home_urlหรือsite_urlหรือใด ๆ ของฟังก์ชั่น URL อื่น

Laravel

request()->getHost()

request()->getHostฟังก์ชั่นจะรับมาจาก Symfony และได้รับการรักษาความปลอดภัยตั้งแต่ 2013 CVE-2013-4752ปะ

Drupal

ตัวติดตั้งยังไม่ได้ทำการรักษาความปลอดภัย ( ปัญหา # 2404259 ) แต่ใน Drupal 8 มีเอกสารคุณสามารถติดตามการตั้งค่าโฮสต์ที่เชื่อถือได้เพื่อความปลอดภัยในการติดตั้ง Drupal หลังจากนั้นคุณสามารถใช้สิ่งต่อไปนี้:

\Drupal::request()->getHost();

กรอบอื่น ๆ

โปรดแก้ไขคำตอบนี้เพื่อรวมวิธีรับโดเมนปัจจุบันในกรอบงานที่คุณชื่นชอบ เมื่อทำเช่นนั้นโปรดรวมลิงก์ไปยังซอร์สโค้ดที่เกี่ยวข้องหรือสิ่งอื่นใดที่จะช่วยให้ฉันตรวจสอบว่าเฟรมเวิร์กกำลังทำสิ่งต่าง ๆ อย่างปลอดภัย




ภาคผนวก

ตัวอย่างการหาประโยชน์:

  1. การวางยาพิษของแคชอาจเกิดขึ้นได้หากบอตเน็ตร้องขอหน้าอย่างต่อเนื่องโดยใช้ส่วนหัวโฮสต์ที่ไม่ถูกต้อง HTML ที่เป็นผลลัพธ์จะมีลิงก์ไปยังเว็บไซต์ของผู้โจมตีที่สามารถหลอกลวงผู้ใช้ของคุณได้ ในตอนแรกลิงก์ที่เป็นอันตรายจะถูกส่งกลับไปที่แฮ็กเกอร์เท่านั้น แต่หากแฮกเกอร์ทำการร้องขอได้เพียงพอหน้าเวอร์ชันที่เป็นอันตรายจะสิ้นสุดลงในแคชของคุณซึ่งจะถูกส่งไปยังผู้ใช้รายอื่น

  2. การโจมตีแบบฟิชชิงอาจเกิดขึ้นได้หากคุณจัดเก็บลิงก์ในฐานข้อมูลตามส่วนหัวของโฮสต์ ตัวอย่างเช่นสมมติว่าคุณเก็บ URL ที่แน่นอนไปยังโปรไฟล์ของผู้ใช้ในฟอรัม ด้วยการใช้ส่วนหัวที่ไม่ถูกต้องแฮ็กเกอร์อาจทำให้ใครก็ตามที่คลิกลิงก์โปรไฟล์ของตนถูกส่งไปยังไซต์ฟิชชิ่ง

  3. พิษการรีเซ็ตรหัสผ่านอาจเกิดขึ้นได้หากแฮ็กเกอร์ใช้ส่วนหัวโฮสต์ที่เป็นอันตรายเมื่อกรอกแบบฟอร์มรีเซ็ตรหัสผ่านสำหรับผู้ใช้รายอื่น จากนั้นผู้ใช้นั้นจะได้รับอีเมลที่มีลิงค์รีเซ็ตรหัสผ่านซึ่งนำไปสู่ไซต์ฟิชชิ่ง

  4. นี่คือตัวอย่างที่เป็นอันตรายเพิ่มเติม

คำเตือนและหมายเหตุเพิ่มเติม:

  • เมื่อusecanonicalnameถูกปิดการใช้งาน$_SERVER['SERVER_NAME']จะถูกเติมด้วยส่วนหัวเดียวกัน$_SERVER['HTTP_HOST']จะใช้ anyways (รวมถึงพอร์ต) นี่คือการตั้งค่าเริ่มต้นของ Apache หากคุณหรือ devops เปิดใช้งานสิ่งนี้คุณก็ไม่เป็นไร - แต่คุณต้องการที่จะพึ่งพาทีมที่แยกจากกันหรืออนาคตของคุณเองสามปีในอนาคต ค่าเริ่มต้น? แม้ว่าสิ่งนี้จะทำให้สิ่งต่าง ๆ มีความปลอดภัย แต่ฉันก็จะไม่ไว้ใจการตั้งค่านี้
  • อย่างไรก็ตาม Redhat จะเปิดใช้งานตามปกติเป็นค่าเริ่มต้น [ แหล่งที่มา ]
  • หากserverAliasถูกใช้ในรายการโฮสต์เสมือนและขอชื่อแทนโดเมน$_SERVER['SERVER_NAME']จะไม่ส่งคืนโดเมนปัจจุบัน แต่จะส่งคืนค่าของคำสั่ง serverName
  • หาก serverName ไม่สามารถได้รับการแก้ไขคำสั่งชื่อโฮสต์ของระบบปฏิบัติการที่ใช้ในสถานที่[แหล่ง]
  • ถ้าส่วนหัวของโฮสต์ที่เหลือออกจากเซิร์ฟเวอร์จะประพฤติตัวเป็นถ้า usecanonical อยู่บน[แหล่ง]
  • ท้ายสุดฉันเพิ่งลองใช้ประโยชน์จากเซิร์ฟเวอร์ท้องถิ่นของฉันและไม่สามารถหลอกส่วนหัวของโฮสต์ได้ ฉันไม่แน่ใจว่ามีการอัปเดตของ Apache ที่แก้ไขปัญหานี้หรือไม่หรือกำลังทำสิ่งผิดปกติ ส่วนหัวนี้จะยังคงใช้ประโยชน์ได้ในสภาพแวดล้อมที่ไม่ได้ใช้โฮสต์เสมือน

คุยโวเล็กน้อย:

     คำถามนี้ได้รับมุมมองนับแสนโดยไม่ต้องพูดถึงปัญหาด้านความปลอดภัยที่เดียว! ไม่ควรเป็นแบบนี้ แต่เพียงเพราะคำตอบของ Stack Overflow เป็นที่นิยมนั่นไม่ได้หมายความว่าปลอดภัย




1
คุณอาจต้องการพูดถึงความแตกต่างระหว่าง home_url และ site_url wordpress.stackexchange.com/a/50605/13
Volomike

1
+1 สำหรับผู้ใช้ wordpress ดีถ้าคุณต้องการตรวจสอบหากติดตั้งใน subdir แต่โปรดทราบว่าคีย์ parse_url: $urlparts['path']ไม่ได้ตั้งค่าหากติดตั้งในไดเรกทอรีรากของโดเมน อื่น$urlparts['path']ส่งคืนไดเรกทอรีย่อย
Jonas Lundman

9

ลอง$_SERVER['SERVER_NAME']ดู

เคล็ดลับ: สร้างไฟล์ PHP ที่เรียกใช้ฟังก์ชันphpinfo()และดูส่วน "ตัวแปร PHP" มีตัวแปรที่มีประโยชน์มากมายที่เราไม่เคยนึกถึง


คุณสามารถลองพิมพ์ $ _SERVER และค้นหาได้ตลอดเวลา

3

ฉันรู้ว่าสิ่งนี้อาจไม่ได้อยู่ในหัวข้อทั้งหมด แต่จากประสบการณ์ของฉันฉันพบว่าการเก็บ WWW-ness ของ URL ปัจจุบันในตัวแปรมีประโยชน์

แก้ไข:นอกจากนี้โปรดดูความคิดเห็นของฉันด้านล่างเพื่อดูว่าสิ่งนี้เกิดขึ้นที่ใด

สิ่งนี้มีความสำคัญเมื่อพิจารณาว่าจะส่งมอบการโทร Ajax ด้วย "www" หรือไม่:

$.ajax("url" : "www.site.com/script.php", ...

$.ajax("url" : "site.com/script.php", ...

เมื่อทำการส่ง Ajax โทรชื่อโดเมนจะต้องตรงกับที่อยู่ในแถบที่อยู่ของเบราว์เซอร์มิฉะนั้นคุณจะมีUncaught SecurityErrorในคอนโซล

ดังนั้นฉันจึงคิดวิธีแก้ปัญหานี้ขึ้นมา:

<?php
    substr($_SERVER['SERVER_NAME'], 0, 3) == "www" ? $WWW = true : $WWW = false;

    if ($WWW) {
        /* We have www.example.com */
    } else {
        /* We have example.com */
    }
?>

จากนั้นขึ้นอยู่กับว่า $ WWW เป็นจริงหรือเท็จให้เรียกใช้ Ajax ที่เหมาะสม

ฉันรู้ว่านี่อาจฟังดูเล็กน้อย แต่นี่เป็นปัญหาทั่วไปที่ง่ายต่อการเดินทาง


OP อย่างชัดเจนถามสำหรับโดเมนและไม่SERVER_NAME
Sebastian G. Marinescu

จริง แต่วันนี้คุณต้องกังวลเกี่ยวกับปัญหา www ด้วย
InfiniteStack

ทำไม? ใน JS window.locationคุณอาจจะมองใน ใน PHP SERVER_NAMEคุณได้
Sebastian G. Marinescu

4
SERVER_NAME ส่งคืน "www.site.com" แม้ว่าจะมีการป้อน "site.com" ลงในแถบที่อยู่ หากคุณใช้ SERVER_NAME ตลอดทั้งรหัสของคุณคุณจะพบปัญหาความปลอดภัยของ www / no-www โดยเฉพาะอย่างยิ่งเมื่อต้องใช้การโทร Ajax แต่เพื่อตอบคำถามของคุณในการเขียนโปรแกรม PHP ขั้นสูงบางครั้ง PHP จำเป็นต้องสร้างรหัสแบบไดนามิกที่ทำให้การเรียก HTTP ไปยังเซิร์ฟเวอร์ หาก URL เป้าหมายมี "www" ในหน้าเว็บที่ไม่มีก็จะสร้างข้อผิดพลาดด้านความปลอดภัย
InfiniteStack

ตกลงตกลง ... ฉันอ่านเกี่ยวกับเรื่องนี้และคุณพูดถูก ดังนั้นคำตอบของคุณอาจเกี่ยวข้องกับใครบางคน Good job :)
Sebastian G. Marinescu

3

ทุกคนใช้parse_urlฟังก์ชั่น แต่บางครั้งผู้ใช้อาจส่งผ่าน argumet ในรูปแบบที่แตกต่างกัน

เพื่อแก้ไขสิ่งนั้นฉันได้สร้างฟังก์ชั่น ลองดู:

function fixDomainName($url='')
{
    $strToLower = strtolower(trim($url));
    $httpPregReplace = preg_replace('/^http:\/\//i', '', $strToLower);
    $httpsPregReplace = preg_replace('/^https:\/\//i', '', $httpPregReplace);
    $wwwPregReplace = preg_replace('/^www\./i', '', $httpsPregReplace);
    $explodeToArray = explode('/', $wwwPregReplace);
    $finalDomainName = trim($explodeToArray[0]);
    return $finalDomainName;
}

เพียงผ่าน URL และรับโดเมน

ตัวอย่างเช่น,

echo fixDomainName('https://stackoverflow.com');

จะส่งคืนผลลัพธ์จะเป็น

stackoverflow.com

และในบางสถานการณ์:

echo fixDomainName('stackoverflow.com/questions/id/slug');

stackoverflow.comและก็ยังจะกลับมา


1
$_SERVER['HTTP_HOST'] 

// เพื่อรับโดเมน

$protocol=strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$domainLink=$protocol.'://'.$_SERVER['HTTP_HOST'];

// โดเมนกับโปรโตคอล

$url=$protocol.'://'.$_SERVER['HTTP_HOST'].'?'.$_SERVER['QUERY_STRING'];

// โปรโตคอล, โดเมน, ข้อความค้นหารวมทั้งหมด ** เนื่องจาก $ _SERVER ['SERVER_NAME'] ไม่น่าเชื่อถือสำหรับการโฮสต์หลายโดเมน!


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.