แชร์คุกกี้ระหว่างโดเมนย่อยและโดเมน


420

ฉันมีสองคำถาม ฉันเข้าใจว่าหากฉันระบุโดเมนเป็น.mydomain.com(ด้วยจุดนำ) ในคุกกี้ที่โดเมนย่อยทั้งหมดสามารถแชร์คุกกี้ได้

สามารถsubdomain.mydomain.comเข้าถึงคุกกี้ที่สร้างขึ้นในmydomain.com(โดยไม่ต้องwwwโดเมนย่อย)?

สามารถmydomain.com(ไม่ใช้wwwโดเมนย่อย) เข้าถึงคุกกี้ได้subdomain.mydomain.comหรือไม่หากสร้างขึ้น


3
ใช่คุณสามารถ .. โปรดดูลิงค์ด้านล่างcodeguru.com/csharp/csharp/cs_internet/article.php/c19417/…
Rahul Jain

เกี่ยวข้องอย่างใกล้ชิด: stackoverflow.com/questions/3089199/…
Ciro Santilli i 冠状病病六四事件法轮功

คุณช่วยโปรดดูที่คำถามนี้stackoverflow.com/questions/38351769/…
Jayavardhan Gange

1
@ adam0101 จะเกิดอะไรขึ้นหากโดเมนและโดเมนย่อยโฮสต์บนเซิร์ฟเวอร์อื่น
user3782114

3
@ user3782114 ไม่สำคัญว่าอยู่บนเซิร์ฟเวอร์อื่นหรือไม่ ในกรณีของฉันพวกเขาไม่เพียง แต่บนเซิร์ฟเวอร์ที่แตกต่างกัน แต่แต่ละโดเมนมีโหลดบาลานซ์ในหลายเซิร์ฟเวอร์ สิ่งหนึ่งที่ทำให้เราเดินทางไม่นานก็คือสภาพแวดล้อมที่ต่ำกว่า (dev, test, uat, etc) เริ่มแชร์คุกกี้เดียวกันด้วยเมื่อเราทำสิ่งนี้เพราะเราตั้งชื่อพวกเขาเช่น "dev.oursite.com", "การทดสอบ oursite.com "ฯลฯ เคล็ดลับที่นั่น (อย่างน้อยก็ใน. Net) คือการสร้างรหัสเครื่องแยกต่างหากสำหรับแต่ละสภาพแวดล้อมและบันทึกไว้ใน Web.config ของคุณ (สมมติว่าคุณเปลี่ยนการกำหนดค่าสำหรับแต่ละสภาพแวดล้อม)
adam0101

คำตอบ:


653

โดเมน 2 แห่งmydomain.comและsubdomain.mydomain.comสามารถแบ่งปันคุกกี้ได้เฉพาะเมื่อมีการระบุชื่อโดเมนไว้อย่างชัดเจนในSet-Cookieส่วนหัว มิฉะนั้นขอบเขตของคุกกี้จะถูก จำกัด ให้กับโฮสต์ที่ร้องขอ (สิ่งนี้เรียกว่า "คุกกี้สำหรับโฮสต์เท่านั้น" ดูคุกกี้ของโฮสต์เท่านั้นคืออะไร )

ตัวอย่างเช่นหากคุณส่งส่วนหัวต่อไปนี้จากsubdomain.mydomain.comนั้นจะไม่ส่งคุกกี้สำหรับคำขอไปที่mydomain.com:

Set-Cookie: name=value

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

Set-Cookie: name=value; domain=mydomain.com

คุกกี้นี้จะถูกส่งไปสำหรับการใด ๆโดเมนย่อยของ mydomain.com subsub.subdomain.mydomain.comรวมทั้งโดเมนย่อยที่ซ้อนกันเช่น

ในRFC 2109โดเมนที่ไม่มีจุดนำหมายความว่าไม่สามารถใช้กับโดเมนย่อยได้และมีเพียงจุดนำหน้า ( .mydomain.com) เท่านั้นที่อนุญาตให้ใช้ได้ในหลายโดเมนย่อย (แต่ไม่ใช่โดเมนระดับบนสุดดังนั้นสิ่งที่คุณถามคือ เป็นไปไม่ได้ในข้อมูลจำเพาะรุ่นเก่า)

อย่างไรก็ตามเบราว์เซอร์ที่ทันสมัยทั้งหมดเคารพข้อกำหนดใหม่RFC 6265และจะละเว้นจุดนำใด ๆ ซึ่งหมายความว่าคุณสามารถใช้คุกกี้ในโดเมนย่อยเช่นเดียวกับโดเมนระดับบนสุด

โดยสรุปหากคุณตั้งค่าคุกกี้เหมือนตัวอย่างที่สองด้านบนmydomain.comมันจะสามารถเข้าถึงได้โดยsubdomain.mydomain.comและในทางกลับกัน นอกจากนี้ยังสามารถใช้เพื่ออนุญาตsub1.mydomain.comและsub2.mydomain.comแบ่งปันคุกกี้

ดูสิ่งนี้ด้วย:


3
ขอบคุณ; ฉันเพิ่มหมายเหตุเกี่ยวกับความสำคัญของจุด
cmbuckley

2
ฉันไม่เข้าใจว่าทำไมคุณไม่เพียงแค่นำ "" บนโดเมนเพื่อความเข้ากันได้สูงสุดกับเก่าและใหม่
Alan Macdonald

12
ในมาตรฐานเก่าคุกกี้ที่domain=.mydomain.comไม่ถูกต้องกับ mydomain.com ที่เปลือยเปล่าดังนั้น RFC สองตัวนี้จึงไม่สามารถใช้งานร่วมกันได้
cmbuckley

4
@ Frank ใช่ฉันรู้ ความคิดเห็นของฉันคือการชี้แจงว่าคำถามของฉันเกี่ยวกับการแบ่งปันคุกกี้ระหว่างโดเมนและโดเมนย่อยไม่ใช่ระหว่างสองโดเมนย่อย
adam0101

3
ฉันไม่แน่ใจว่าจะใส่ที่ใดดังนั้นฉันจึงเลือกความคิดเห็นของคำตอบที่ยอมรับได้ ใช้เวลานานและการทดลองที่ล้มเหลวในการพิสูจน์ข้อมูลข้างต้นใน localhost ของฉันจนกว่าจะเกิดขึ้นกับฉันที่ฉันควรจะเรียก localhost ด้วยจุดในชื่อ เช่น "localhost.com" หรืออะไรทำนองนั้น จากนั้นพฤติกรรม "คุกกี้ชุด" ทั้งหมดเริ่มต้นตามคำอธิบายที่เขียนไว้ในคำตอบนี้ หวังว่านี่จะช่วยใครซักคน
Cesc

32

ฉันไม่แน่ใจว่าคำตอบ @cmbuckley กำลังแสดงภาพเต็ม สิ่งที่ฉันอ่านคือ:

เว้นแต่ว่าแอตทริบิวต์ของคุกกี้ระบุไว้เป็นอย่างอื่นคุกกี้จะถูกส่งกลับไปยังเซิร์ฟเวอร์ต้นทางเท่านั้น (และไม่ใช่ตัวอย่างเช่นไปยังโดเมนย่อยใด ๆ ) และหมดอายุเมื่อสิ้นสุดเซสชันปัจจุบัน (ตามที่กำหนดโดยตัวแทนผู้ใช้) ตัวแทนผู้ใช้ไม่สนใจคุกกี้ที่ไม่รู้จัก

RFC 6265

ด้วย

8.6.  Weak Integrity

   Cookies do not provide integrity guarantees for sibling domains (and
   their subdomains).  For example, consider foo.example.com and
   bar.example.com.  The foo.example.com server can set a cookie with a
   Domain attribute of "example.com" (possibly overwriting an existing
   "example.com" cookie set by bar.example.com), and the user agent will
   include that cookie in HTTP requests to bar.example.com.  In the
   worst case, bar.example.com will be unable to distinguish this cookie
   from a cookie it set itself.  The foo.example.com server might be
   able to leverage this ability to mount an attack against
   bar.example.com.

สำหรับฉันนั่นหมายความว่าคุณสามารถป้องกันคุกกี้จากการอ่านโดยโดเมนย่อย / โดเมน แต่ไม่สามารถป้องกันการเขียนคุกกี้ไปยังโดเมนอื่น ๆ ดังนั้นบางคนอาจเขียนคุกกี้เว็บไซต์ของคุณอีกครั้งโดยควบคุมโดเมนย่อยอื่นที่เข้าชมโดยเบราว์เซอร์เดียวกัน ซึ่งอาจไม่ใช่เรื่องใหญ่

เว็บไซต์ทดสอบคุกกี้สุดเจ๋งจัดทำโดย @cmbuckley / สำหรับผู้ที่ไม่ได้รับคำตอบเช่นฉัน เลื่อนขึ้นและ upvoting มูลค่า:


4
ที่ดูเหมือนจะเห็นด้วยกับสิ่งที่ฉันพูด: เว้นแต่คุณจะระบุdomain, คุกกี้จะใช้สำหรับโฮสต์คำขอเท่านั้น ซึ่งหมายความว่าSet-Cookie: name=valueจากmydomain.comนี้จะไม่ถูกส่งไปพร้อมกับการร้องขอไปยังโดเมนย่อย ลองเล่นกับสคริปต์ทดสอบนี้ด้วย
cmbuckley

@cmbuckley โอเคสิ่งที่คุณพูดถูกต้องแล้ว ฉันจะพูดคำตอบของฉันอีกครั้ง ขอบคุณสำหรับการชี้ให้เห็นว่า
akostadinov

จำเป็นต้องชี้ให้เห็นว่าส่วนที่ 4.1.2 (การอ้างอิงแรก) ไม่ได้เป็นบรรทัดฐาน ...
Velda

ขอบคุณสำหรับลิงค์ cmbuckley ยินดีที่ได้ทดสอบวิธีการทำงานอย่างรวดเร็ว
lawphotog

22

นี่คือตัวอย่างการใช้ DOM cookie API ( https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie ) เพื่อให้เราเห็นพฤติกรรมของเรา

หากเรารัน JavaScript ต่อไปนี้:

document.cookie = "key = value"

ดูเหมือนว่าจะเหมือนกับการดำเนินการ:

document.cookie = "key = value; domain = mydomain.com"

คุกกี้ที่สำคัญกลายเป็นใช้ได้ (เท่านั้น) บนโดเมนmydomain.com


ตอนนี้ถ้าคุณรัน JavaScript ต่อไปนี้บน mydomain.com:

document.cookie = "key = value; domain = .mydomain.com"

คุกกี้ที่สำคัญกลายเป็นใช้ได้กับmydomain.comเช่นเดียวกับsubdomain.mydomain.com


สุดท้ายถ้าคุณต้องลองและดำเนินการต่อไปนี้ใน subdomain.mydomain.com:

document.cookie = "key = value; domain = .mydomain.com"

คีย์คุกกี้สามารถใช้ได้กับsubdomain.mydomain.comหรือไม่ ฉันรู้สึกประหลาดใจเล็กน้อยที่ได้รับอนุญาต ฉันสันนิษฐานว่าน่าจะเป็นการละเมิดความปลอดภัยสำหรับโดเมนย่อยเพื่อให้สามารถตั้งค่าคุกกี้ในโดเมนหลัก


1
นี่ทำให้ฉันสงสัยว่ามีรายละเอียดแยกต่างหากที่อธิบายพฤติกรรมของhttponlyคุกกี้กับชนิดของคุกกี้ที่คุณกำลังสร้าง
adam0101

3
เอกสารที่คุณโพสต์ไม่เห็นด้วยกับข้อความที่คุณทำ ตัวอย่าง 2 ตัวอย่างแรกนั้นไม่เทียบเท่ากัน ( domainแอตทริบิวต์ทำให้คุกกี้ทำงานบนโดเมนย่อยโดยไม่มีแอตทริบิวต์ดังกล่าว) จุดนำจะถูกมองข้ามที่ดีที่สุดและถูกบล็อกอย่างแข็งขันที่สุด
cmbuckley

นี่เป็นทางออกที่ดีที่สุดหากคุณไม่ต้องการพึ่งพาส่วนหัวของโฮสต์ ฉันตรวจสอบแล้วและมันทำงาน
Szymon

14

โปรดทราบว่าคุณสามารถตั้งค่าคุกกี้จากโดเมนย่อยบนโดเมน

(ส่งในการตอบกลับสำหรับการร้องขอsubdomain.mydomain.com)

Set-Cookie: name=value; Domain=mydomain.com // GOOD

แต่คุณไม่สามารถตั้งค่าคุกกี้จากโดเมนบนโดเมนย่อย

(ส่งในการตอบกลับสำหรับการร้องขอmydomain.com)

Set-Cookie: name=value; Domain=subdomain.mydomain.com // Browser rejects cookie

ทำไม

ตามข้อกำหนดRFC 6265 ส่วน 5.3.6 รูปแบบการจัดเก็บ

หาก canonicalized request-host ไม่ตรงกับโดเมน domain-attribute: ละเว้นคุกกี้ทั้งหมดและยกเลิกขั้นตอนเหล่านี้

และRFC 6265 ส่วน 5.1.3 การจับคู่โดเมน

การจับคู่โดเมน

สตริงโดเมนตรงกับสตริงโดเมนที่ระบุหากมีเงื่อนไขอย่างน้อยหนึ่งข้อต่อไปนี้:

  1. สตริงโดเมนและสตริงเหมือนกัน (โปรดทราบว่าทั้งโดเมนสตริงและสตริงจะได้รับการแปลงเป็นตัวพิมพ์เล็กถึงจุดนี้)

  2. มีเงื่อนไขดังต่อไปนี้ทั้งหมด:

    • สตริงโดเมนคือส่วนต่อท้ายของสตริง

    • อักขระตัวสุดท้ายของสตริงที่ไม่รวมอยู่ในสตริงโดเมนคืออักขระ% x2E (".")

    • สตริงเป็นชื่อโฮสต์ (เช่นไม่ใช่ที่อยู่ IP)

ดังนั้น "subdomain.mydomain.com" ตรงกับโดเมน "mydomain.com" แต่ "mydomain.com" ไม่ตรงกับโดเมน "subdomain.mydomain.com"

ตรวจสอบคำตอบนี้ด้วย


นี่เป็นคำตอบที่มีประโยชน์ที่สุดสำหรับฉัน
Toby

3

ในทั้งสองกรณีใช่มันสามารถทำได้และนี่เป็นพฤติกรรมเริ่มต้นสำหรับทั้ง IE และ Edge

คำตอบอื่น ๆ เพิ่มความเข้าใจที่มีคุณค่า แต่อธิบายพฤติกรรมส่วนใหญ่ใน Chrome สิ่งสำคัญคือต้องทราบว่าพฤติกรรมนั้นแตกต่างอย่างสิ้นเชิงใน IE สคริปต์ทดสอบที่เป็นประโยชน์อย่างมากของ CMBuckley แสดงให้เห็นว่าใน Chrome จะไม่แบ่งปันคุกกี้ระหว่างรูทและโดเมนย่อยเมื่อไม่มีการระบุโดเมน อย่างไรก็ตามการทดสอบเดียวกันใน IE แสดงให้เห็นว่าพวกเขาจะใช้ร่วมกัน กรณี IE นี้ใกล้เคียงกับคำอธิบายการนำกลับบ้านในลิงก์ www-or-not-www ของ CMBuckley ฉันรู้ว่านี่เป็นกรณีเพราะเรามีระบบที่ใช้คุกกี้ servicestack ที่แตกต่างกันทั้งในรูทและโดเมนย่อย ทุกอย่างทำงานได้ดีจนกระทั่งมีคนเข้าใช้งานใน IE และทั้งสองระบบต่อสู้กันโดยที่คุกกี้เซสชันจะชนะจนกว่าเราจะล้างแคช


0

ระวังถ้าคุณกำลังทำงานบน localhost! หากคุณเก็บคุกกี้ของคุณใน js เช่นนี้:

document.cookie = "key=value;domain=localhost"

sub.localhostมันอาจจะไม่สามารถเข้าถึงโดเมนย่อยของคุณเช่น เพื่อที่จะแก้ปัญหานี้คุณจำเป็นต้องใช้โฮสต์เสมือน สำหรับตัวอย่างคุณสามารถกำหนดค่าโฮสต์เสมือนของคุณได้ServerName localhost.comจากนั้นคุณจะสามารถจัดเก็บคุกกี้ของคุณในโดเมนและโดเมนย่อยของคุณดังนี้:

document.cookie = "key=value;domain=localhost.com"

-12

ทางออกที่ง่าย

setcookie("NAME", "VALUE", time()+3600, '/', EXAMPLE.COM);

พารามิเตอร์ลำดับที่ 5 ของ Setcookie กำหนดโดเมน (ย่อย) ที่คุกกี้มีให้ การตั้งค่าเป็น (EXAMPLE.COM) ทำให้สามารถใช้ได้กับโดเมนย่อยใด ๆ (เช่น: SUBDOMAIN.EXAMPLE.COM)

การอ้างอิง: http://php.net/manual/th/function.setcookie.php


17
คำถามนี้ไม่เฉพาะ PHP ฉันไม่คิดว่ามันมีคุณสมบัติเหมาะสม
sergelerator

1
Sergelerator ฉันไม่ได้ถามคำถาม ฉันตอบสนองต่อ OP
ฏหมาย

4
@ Lawes ฉันเชื่อว่า sergelator หมายถึงคำถามของ OP ไม่ใช่ PHP ที่เฉพาะเจาะจงในขณะที่คำตอบของคุณดูเหมือนจะเป็นทางออกของ PHP เท่านั้นดังนั้นมันจึงไม่ตรงกับคำถามของ OP
Mirage
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.