ความแตกต่างระหว่างการเปลี่ยนเส้นทาง 302 และ 307 คืออะไร


208

ความแตกต่างระหว่าง a 302 FOUNDและการ307 TEMPORARY REDIRECTตอบสนอง HTTP คืออะไร?

ข้อมูลจำเพาะ W3ดูเหมือนว่าบ่งบอกว่าพวกเขาทั้งคู่ใช้สำหรับการเปลี่ยนเส้นทางชั่วคราวและไม่สามารถแคชได้เว้นแต่ว่าการตอบกลับจะอนุญาตเฉพาะ

คำตอบ:


99

ความกังวลที่แตกต่างเปลี่ยนเส้นทางPOST, PUTและDELETEการร้องขอและสิ่งที่คาดหวังของเซิร์ฟเวอร์ที่มีพฤติกรรมตัวแทนของผู้ใช้ ( RFC 2616):

หมายเหตุ: RFC 1945 และ RFC 2068 ระบุว่าลูกค้าไม่ได้รับอนุญาตให้เปลี่ยนวิธีในคำขอเปลี่ยนเส้นทาง อย่างไรก็ตามการปรับใช้ตัวแทนผู้ใช้ที่มีอยู่ส่วนใหญ่ถือว่า 302 ราวกับว่าเป็นการตอบสนอง 303 การดำเนินการ GET บนค่าฟิลด์สถานที่โดยไม่คำนึงถึงวิธีการร้องขอดั้งเดิม รหัสสถานะ 303 และ 307 ถูกเพิ่มเข้ามาสำหรับเซิร์ฟเวอร์ที่ต้องการทำให้เกิดความชัดเจนว่าลูกค้าจะทำปฏิกิริยาแบบใด

นอกจากนี้อ่านบทความวิกิพีเดียในรหัสการเปลี่ยนเส้นทาง 30x


ดังนั้นจากมุมมอง parser / agent / browser เราสามารถปฏิบัติต่อ 302 และ 307 เหมือนกันใช่ไหม? (ในที่แน่นอนชิ้นเดียวกันของรหัสสามารถนำมาใช้ในการจัดการทั้งสองกรณีโดยไม่ต้อง distinguishment ต่อไป?)
Pacerier

ไม่ - คุณสามารถปฏิบัติต่อ 302 และ 303 เหมือนกัน แต่ 307 นั้นแตกต่างกัน
Quentin Skousen

@kkhugs, ไม่เป็นไร, ต้องใช้เบราว์เซอร์ 1.0 ในการรับ -305 เช่นเดียวกับ get-307 ในเบราว์เซอร์ 1.1 จำเป็นต้องใช้เบราว์เซอร์ 1.0 เพื่อทำการโพสต์-302 เช่นเดียวกับที่ได้รับ -307 ยกเว้นว่าต้องทำการยืนยันผู้ใช้ก่อนเพื่อดำเนินการต่อและจะต้องโพสต์วิธีการนั้น
Pacerier

จำเป็นต้องใช้เบราว์เซอร์ 1.1 เพื่อรับ-302 เช่นเดียวกับที่รับ -307
Pacerier

161

307 เกิดขึ้นเพราะตัวแทนผู้ใช้ที่นำมาใช้เป็นพฤติกรรมพฤตินัยในการรับคำขอ POST ที่ได้รับการตอบสนอง 302 และส่งคำขอ GET ไปยังส่วนหัว Location response

นั่นคือพฤติกรรมที่ไม่ถูกต้อง - เฉพาะ 303 เท่านั้นที่ทำให้ POST เปลี่ยนเป็น GET ตัวแทนผู้ใช้ควร (แต่ไม่) ติดกับวิธีการ POST เมื่อขอ URL ใหม่หากคำขอ POST ดั้งเดิมส่งคืน 302

307 ได้รับการแนะนำให้อนุญาตให้เซิร์ฟเวอร์บอกกับตัวแทนผู้ใช้ว่าลูกค้าไม่ควรทำการเปลี่ยนวิธีเมื่อทำตามหัวข้อการตอบสนองตำแหน่ง


3
ตัวอย่างใด ๆ ของตัวแทนผู้ใช้ที่ตอบสนองไม่ถูกต้อง? โดยปกติแล้วจะมีผู้เข้าชมเพียงเล็กน้อยเท่านั้น
goodguys_activate

6
@ makerofthings7 เบราว์เซอร์ทั้งหมดจัดการ302อย่างไม่ถูกต้อง Chrome 30, IE10 มันกลายเป็นการใช้งานที่ไม่ถูกต้องอย่างแท้จริง ที่ไม่สามารถเปลี่ยนแปลงได้เนื่องจากมีเว็บไซต์จำนวนมากออกมาผิดพลาด 302 ในความเป็นจริง ASP.net MVC ออกมาไม่ถูกต้อง 302 ขึ้นอยู่กับความจริงที่ว่าเบราว์เซอร์จัดการมันไม่ถูกต้อง
เอียนบอยด์

1
@IanBoyd เฉพาะเฟรมเวิร์กเหตุผลที่ทำเช่นนี้เนื่องจาก303ได้รับการแนะนำ307ในข้อกำหนดคุณสมบัติ HTTP 1.1 และอนุญาตให้เข้ากันได้กับเอเจนต์ผู้ใช้ HTTP 1.0 ย้อนหลัง แน่นอนคำถามจริงคือเราควรจะยังจัดการกับตัวแทนผู้ใช้ HTTP 1.0 ได้หรือไม่?
ewanm89

1
@ ewanm89 ดูเหมือนว่าเฟรมเวิร์กอาจสร้างวิธีการตอบกลับที่มีชื่ออย่างเหมาะสม (เช่น Response.RedirectSeeOther ) และในกรณีที่ลูกค้าไม่ได้เป็น 1.1 (เช่นGET /foo.html, GET /foo.html HTTP/1.0) 302แล้วออกเดิม
Ian Boyd

ดูเหมือนว่า 302 = 303 เมื่อเปลี่ยนเส้นทาง
วี

60

ตัวอย่างที่ดีของการ307 Internal Redirectดำเนินการคือเมื่อ Google Chrome พบการโทร HTTP ไปยังโดเมนที่รู้ว่าต้องใช้ Strict Transport Security

เบราว์เซอร์เปลี่ยนเส้นทางอย่างราบรื่นโดยใช้วิธีเดียวกันกับการโทรเดิม

HTST 307 การเปลี่ยนเส้นทางภายใน


2
คุณรู้หรือไม่เมื่อ Google ใช้คุณสมบัตินี้?
Tijme

2
ใช่นี่คือสิ่งที่ฉันเห็นมันเกิดขึ้น - เซิร์ฟเวอร์ของเราไม่ได้ส่งมัน - ใน Chrome devtools ดูเหมือนว่ามันจะเป็น แต่มันก็แค่การเปลี่ยนทิศทางของ Chrome เพราะเรามีส่วนหัว Strict Transport Security
ไมค์เนลสัน

16

ผัง

  • 301: การเปลี่ยนเส้นทางถาวร: URL เก่าและควรถูกแทนที่ เบราว์เซอร์จะแคชสิ่งนี้
    ตัวอย่างการใช้งาน: URL ถูกย้ายจาก/register-form.htmlsignup-form.htmlไป
    วิธีการจะเปลี่ยนเป็น GET ตาม RFC 7231: "ด้วยเหตุผลในอดีตตัวแทนผู้ใช้อาจเปลี่ยนวิธีการร้องขอจาก POST เป็น GET สำหรับคำขอที่ตามมา"
  • 302: การเปลี่ยนเส้นทางชั่วคราว ใช้สำหรับไคลเอ็นต์ HTTP / 1.0 เท่านั้น รหัสสถานะนี้ไม่ควรเปลี่ยนวิธีการ แต่เบราว์เซอร์ทำเช่นนั้น RFC พูดว่า: "ตัวแทนผู้ใช้ pre-HTTP / 1.1 จำนวนมากไม่เข้าใจ [303] เมื่อความกังวลเกี่ยวกับการทำงานร่วมกันกับไคลเอนต์นั้นรหัสสถานะ 302 อาจถูกใช้แทนเนื่องจากตัวแทนผู้ใช้ส่วนใหญ่ตอบสนองต่อการตอบสนอง 302 ตามที่อธิบายไว้ที่นี่ สำหรับ 303. " แน่นอนว่าลูกค้าบางรายอาจใช้งานได้ตามข้อกำหนดดังนั้นหากการทำงานร่วมกันกับลูกค้าโบราณดังกล่าวไม่ใช่เรื่องจริง 303 จะดีกว่าสำหรับผลลัพธ์ที่สอดคล้องกัน
  • 303: เปลี่ยนเส้นทางชั่วคราวเปลี่ยนวิธีเป็น GET
    ตัวอย่างการใช้งาน:หากเบราว์เซอร์ส่ง POST ไปให้/register.phpโหลดทันที (GET)/success.htmlทันที
  • 307: เปลี่ยนเส้นทางชั่วคราวทำซ้ำการร้องขอเหมือนกัน
    ตัวอย่างการใช้งาน:หากเบราว์เซอร์ส่ง POST ไปให้/register.phpแล้วนี้บอกว่ามันทำซ้ำ POST /signup.phpที่
  • 308: การเปลี่ยนเส้นทางถาวรโดยทำซ้ำการร้องขอเหมือนกัน โดยที่ 307 คือคู่ "no method change" ของ 303 สถานะ 308 นี้คือคู่ "no method change" 301

RFC 7231 (จาก 2014)สามารถอ่านได้มากและไม่ได้รับรายละเอียดมากเกินไป หากคุณต้องการทราบคำตอบที่แน่นอนแนะนำให้อ่าน คำตอบอื่น ๆ ใช้ RFC 2616 จากปี 1999 แต่ไม่มีอะไรเปลี่ยนแปลง

RFC 7238ระบุสถานะ 308 ถือว่าเป็นการทดลอง แต่ได้รับการสนับสนุนแล้วโดยเบราว์เซอร์หลักทั้งหมดในปี 2559


302 จะไม่คัดค้าน
Julian Reschke

@JulianReschke Wikipedia พูดว่า "302 ถูกแทนที่โดย 303 และ 307" อาจเป็นเพราะฉันไม่ใช่เจ้าของภาษา แต่สำหรับฉัน (ในบริบทนี้) ถูกแทนที่และเลิกใช้หมายความว่าเหมือนกัน: ใช้ 303 หรือ 307 แต่ไม่ใช่ 302 ฉันอ่านผิดหรือเปล่า?
Luc

มีอะไรผิดปกติคือสมมติฐานที่ Wikipedia ได้กล่าวไว้ หาก 302 เลิกใช้แล้ว HTTP จะพูดเช่นนั้น
Julian Reschke

@JulianReschke ยุติธรรมพอฉันไปที่แหล่งและ waddayaknow? คุณพูดถูก RFCนั้นเป็นที่เข้าใจได้ดีมากและแน่นอนพวกเขายังแนะนำ 302 ภายใต้เงื่อนไขบางประการ ไม่มีการ "อัปเดตโดย" และ "เลิกใช้งานโดย" RFCs ที่กล่าวถึงด้านบนเป็นเรื่องเกี่ยวกับรหัสสถานะดังนั้นฉันเดาว่าเอกสาร 1999 นี้เป็นเอกสารล่าสุดที่เรามี ฉันจะอัปเดตคำตอบของฉัน
Luc

สิ่งที่เกี่ยวข้องคือการลงทะเบียนรหัสสถานะของ IANA และในกรณีนี้ RFC 7231
Julian Reschke

8

คาดหวังสำหรับ 302: การเปลี่ยนเส้นทางใช้วิธีการร้องขอเดียวกันกับ POST ใน NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL

จริงสำหรับ 302, 303: เปลี่ยนวิธีการร้องขอเปลี่ยนเส้นทางจาก POST เป็น GET ใน NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)

ACTUAL สำหรับ 307: การเปลี่ยนเส้นทางใช้วิธีคำขอเดียวกัน POST ใน NEW_URL

CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL

2

302 เป็นการเปลี่ยนเส้นทางชั่วคราวซึ่งสร้างโดยเซิร์ฟเวอร์ในขณะที่ 307 เป็นการตอบสนองการเปลี่ยนเส้นทางภายในที่สร้างโดยเบราว์เซอร์ การเปลี่ยนเส้นทางภายในหมายความว่าการเปลี่ยนเส้นทางจะกระทำโดยอัตโนมัติโดยเบราว์เซอร์ภายในโดยทั่วไปเบราว์เซอร์จะเปลี่ยน URL ที่ป้อนจาก http ไปยัง https เพื่อรับคำขอด้วยตัวเองก่อนที่จะทำการร้องขอดังนั้นการร้องขอสำหรับการเชื่อมต่อที่ไม่ปลอดภัย เบราว์เซอร์จะเปลี่ยน URL เป็น https หรือไม่ขึ้นอยู่กับรายการโหลดล่วงหน้าที่มาพร้อมกับเบราว์เซอร์ล่วงหน้า นอกจากนี้คุณยังสามารถเพิ่มไซต์ใดก็ได้ที่รองรับ https ไปยังรายการโดยป้อนโดเมนในรายการโหลดเบราว์เซอร์ของคุณซึ่งอยู่ที่ chrome: //net-internals/#hsts.One สามารถเพิ่มโดเมนเว็บไซต์อื่นได้อีกโดยเจ้าของ เพื่อโหลดรายการล่วงหน้าโดยกรอกแบบฟอร์มที่ https://hstspreload.org/เพื่อให้มีการติดตั้งไว้ล่วงหน้าในเบราว์เซอร์สำหรับผู้ใช้ทุกคนแม้ว่าฉันจะพูดถึงว่าคุณสามารถทำได้ด้วยตัวคุณเองโดยเฉพาะ


ให้ฉันอธิบายด้วยตัวอย่าง:
ฉันได้รับคำขอไปยังhttp://www.pentesteracademy.comซึ่งรองรับเฉพาะ https และฉันไม่มีโดเมนนั้นในรายการโหลดล่วงหน้า hsts ของฉันบนเบราว์เซอร์เนื่องจากเจ้าของไซต์ไม่ได้ลงทะเบียน เพื่อมาพร้อมกับรายการโหลด hsts ที่ติดตั้งล่วงหน้า คำขอ GET สำหรับรุ่นที่ไม่ปลอดภัยของเว็บไซต์จะถูกเปลี่ยนเส้นทางไปยังรุ่นที่ปลอดภัย (ดูที่ส่วนหัว http ชื่อสถานที่สำหรับการตอบสนองในภาพด้านบน) ตอนนี้ฉันเพิ่มไซต์ลงในรายการโหลดล่วงหน้าของเบราว์เซอร์ของฉันโดยเพิ่มโดเมนในเพิ่มรูปแบบโดเมน hsts ที่ chrome: // net-internals / # hsts ซึ่งแก้ไขรายการโหลดล่วงหน้าส่วนบุคคลของฉันในเบราว์เซอร์ chrome ของฉันแน่ใจว่าเลือกรวมโดเมนย่อยสำหรับ ตัวเลือก STS เรามาดูคำขอและการตอบสนองสำหรับเว็บไซต์เดียวกันทันทีหลังจากเพิ่มลงในรายการโหลดล่วงหน้า hstsส่วนหัวคำขอและตอบกลับ



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


2

แต่เดิมมีเพียง 302

| Response               | What browsers should do   |
|------------------------|---------------------------|
| 302 Found              | Redo request with new url |

ความคิดคือ:

  • หากคุณกำลังทำGETบางสถานที่คุณจะทำซ้ำGETURL ใหม่ของคุณ
  • หากคุณกำลังทำPOSTบางสถานที่คุณจะทำซ้ำPOSTURL ใหม่ของคุณ
  • หากคุณกำลังทำPUTบางสถานที่คุณจะทำซ้ำPUTURL ใหม่ของคุณ
  • หากคุณกำลังทำDELETEบางสถานที่คุณจะทำซ้ำDELETEURL ใหม่ของคุณ
  • ฯลฯ

น่าเสียดายที่ทุกเบราว์เซอร์ทำผิด เมื่อรับ a 302พวกเขาจะเปลี่ยนไปGETที่ URL ใหม่แทนที่จะลองอีกครั้งโดยใช้คำกริยาเดียวกัน ( เช่น , POST):

  • โมเสกทำผิด
  • Netscape คัดลอกข้อบกพร่องใน Mosaic; พวกเขาเข้าใจผิด
  • Internet Explorer คัดลอกข้อบกพร่องใน Netscape; พวกเขาเข้าใจผิด

มันกลายเป็นความจริงผิด

เบราว์เซอร์ทั้งหมด302ผิดพลาด ดังนั้น303และ307ถูกสร้างขึ้น

| การตอบสนอง | เบราว์เซอร์ใดที่ควรทำ | เบราว์เซอร์ใดที่ทำจริง | | ------------------------ | ------------------------ --- | --------------------------- | | พบ 302 | ทำซ้ำคำขอด้วย url ใหม่ รับด้วย url ใหม่ | 303 ดูอื่น ๆ | รับด้วย url ใหม่ รับด้วย url ใหม่ | 307 การเปลี่ยนเส้นทางชั่วคราว ทำซ้ำคำขอด้วย url ใหม่ ทำซ้ำคำขอด้วย url ใหม่

ในรูปแบบแผนภูมิ

การเปลี่ยนเส้นทาง 5 แบบ:

╔═══════════╤════════════════════════════════════════════════╗
║           │                Switch to GET?                  ║
║ Temporary │          No            │         Yes           ║
╠═══════════╪════════════════════════╪═══════════════════════╣
║ No        │ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────┼────────────────────────┼───────────────────────╢
║ Yes       │ 307 Temporary Redirect │ 303 See Other         ║
║           │ 302 Found (intended)   │ 302 Found (actual)    ║
╚═══════════╧════════════════════════╧═══════════════════════╝

อีกวิธีหนึ่งคือ:

| Response                 | Switch to get? | Temporary? |
|--------------------------|----------------|------------|
| 301 Moved Permanently    | No             | No         |
| 302 Found (intended)     | No             | Yes        |
| 302 Found (actual)       | Yes            | Yes        |
| 303 See Other            | Yes            | Yes        |
| 307 Temporary Redirect   | No             | Yes        |
| 308 Permanent Redirect   | No             | No         |

1

นอกจากนี้สำหรับผู้ดูแลระบบเซิร์ฟเวอร์อาจเป็นสิ่งสำคัญที่จะต้องทราบว่าเบราว์เซอร์อาจแสดงพรอมต์ต่อผู้ใช้หากคุณใช้การเปลี่ยนเส้นทาง 307

ตัวอย่างเช่น *, Firefox และ Opera จะถามผู้ใช้เพื่อขออนุญาตเปลี่ยนเส้นทางในขณะที่ Chrome, IE และ Safari จะทำการเปลี่ยนเส้นทางอย่างโปร่งใส

* ต่อBulletproof SSL และ TLS (หน้า 192)


สิ่งนี้เป็นจริงสำหรับคำขอที่ไม่ปลอดภัยเช่น POST เท่านั้น
Julian Reschke

0

ในบางกรณีการใช้งาน 307 การเปลี่ยนเส้นทางอาจถูกทารุณกรรมโดยผู้โจมตีเพื่อเรียนรู้ข้อมูลประจำตัวของเหยื่อ

ข้อมูลเพิ่มเติมสามารถดูได้ในส่วน 3.1ของการวิเคราะห์ความปลอดภัยที่เป็นทางการแบบครอบคลุมของ OAuth 2.02.0

ผู้เขียนบทความข้างต้นแนะนำต่อไปนี้:

แก้ไข ตรงกันข้ามกับถ้อยคำปัจจุบันในมาตรฐาน OAuth วิธีการเปลี่ยนเส้นทางที่แน่นอนไม่ใช่รายละเอียดการนำไปใช้ แต่จำเป็นสำหรับความปลอดภัยของ OAuth ในมาตรฐาน HTTP ( RFC 7231 ) เฉพาะการเปลี่ยนเส้นทาง 303 เท่านั้นที่กำหนดไว้อย่างไม่น่าเชื่อเพื่อวางเนื้อหาของคำขอ HTTP POST รหัสสถานะการเปลี่ยนเส้นทาง HTTP อื่น ๆ ทั้งหมดรวมถึง 302 ที่ใช้บ่อยที่สุดปล่อยให้เบราว์เซอร์เป็นตัวเลือกในการรักษาคำขอ POST และข้อมูลฟอร์ม ในทางปฏิบัติโดยทั่วไปเบราว์เซอร์จะเขียนคำขอ GET ซ้ำซึ่งจะทำให้ข้อมูลฟอร์มยกเว้นการเปลี่ยนเส้นทาง 307 ดังนั้นมาตรฐาน OAuth ควรต้องการการเปลี่ยนเส้นทาง 303 ครั้งสำหรับขั้นตอนที่กล่าวถึงข้างต้นเพื่อแก้ไขปัญหานี้

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