Sự khác biệt giữa chuyển hướng 302 và 307 là gì?


208

Sự khác biệt giữa một là gì 302 FOUNDvà một 307 TEMPORARY REDIRECTHTTP response?

Thông số W3 dường như chỉ ra rằng cả hai đều được sử dụng cho các chuyển hướng tạm thời và không thể lưu vào bộ đệm trừ khi phản hồi cho phép cụ thể.

Câu trả lời:


99

Sự khác biệt liên quan đến chuyển hướng POST, PUTDELETEcác yêu cầu và những gì mong đợi của máy chủ đối với hành vi tác nhân người dùng ( RFC 2616):

Lưu ý: RFC 1945 và RFC 2068 chỉ định rằng máy khách không được phép thay đổi phương thức theo yêu cầu được chuyển hướng. Tuy nhiên, hầu hết các triển khai tác nhân người dùng hiện tại đều xử lý 302 như thể đó là phản hồi 303, thực hiện GET trên giá trị trường Vị trí bất kể phương thức yêu cầu ban đầu. Các mã trạng thái 303 và 307 đã được thêm vào cho các máy chủ muốn làm rõ ràng rõ ràng loại phản ứng nào được mong đợi của khách hàng.

Ngoài ra, đọc bài viết Wikipedia về mã chuyển hướng 30x .


Vì vậy, từ góc độ trình phân tích cú pháp / tác nhân / trình duyệt, chúng ta chỉ đơn giản có thể coi 302 và 307 là giống hệt nhau phải không? (Có thể sử dụng cùng một đoạn mã chính xác để xử lý cả hai trường hợp mà không cần phân biệt thêm?)
Pacerier 17/1/2016

Không - bạn có thể coi 302 và 303 là giống hệt nhau, nhưng 307 thì khác.
Quentin Skousen

@kkhugs, Không thể nào, trình duyệt 1.0 được yêu cầu để thực hiện get-302 giống như cách get-307 được thực hiện trong 1.1 trình duyệt. Cần có trình duyệt 1.0 để thực hiện post-302 theo cách tương tự như get-302, ngoại trừ trước tiên nó phải yêu cầu xác nhận người dùng để tiếp tục và phương thức phải được đăng.
Pacerier

Cần có trình duyệt 1.1 để thực hiện get-302 giống như cách sử dụng get-307.
Pacerier

161

307 xuất hiện do các tác nhân người dùng được thông qua như một hành vi thực tế để nhận các yêu cầu POST nhận được phản hồi 302 và gửi yêu cầu GET đến tiêu đề phản hồi Vị trí.

Đó là hành vi không chính xác - chỉ một 303 nên khiến POST biến thành GET. Tác nhân người dùng nên (nhưng không) gắn bó với phương thức POST khi yêu cầu URL mới nếu yêu cầu POST ban đầu trả về 302.

307 được giới thiệu để cho phép các máy chủ làm rõ cho tác nhân người dùng rằng máy khách không nên thay đổi phương thức khi thực hiện theo tiêu đề phản hồi Vị trí.


3
Bất kỳ ví dụ về các tác nhân người dùng phản hồi không chính xác? Có phải thường là một tỷ lệ rất nhỏ của khách truy cập?
goodguys_activate

6
@ Makerofthings7 Tất cả các trình điều khiển xử lý 302không chính xác. Chrome 30, IE10. Nó trở thành thực tế không chính xác; điều đó không thể thay đổi được vì rất nhiều trang web gặp sự cố nhầm lẫn 302. Trong thực tế, ASP.net MVC không đúng vấn đề 302, tùy thuộc vào thực tế là các trình duyệt xử lý không chính xác.
Ian Boyd

1
@IanBoyd Chỉ các khung lý do làm điều này là do 303cũng được giới thiệu 307trong đặc tả HTTP 1.1 và do đó cho phép tương thích ngược với các tác nhân người dùng HTTP 1.0. Tất nhiên, câu hỏi thực sự là liệu chúng ta có nên xử lý các tác nhân người dùng HTTP 1.0 không?
ewanm89

1
@ ewanm89 Có vẻ là rằng khuôn khổ có thể tạo ra các phương pháp phản ứng có tên đúng (ví dụ Response.RedirectSeeOther), và nếu khách hàng không phải là 1,1 (ví dụ GET /foo.html, GET /foo.html HTTP/1.0) sau đó phát hành các di sản 302.
Ian Boyd

Nó trông giống như 302 = 303 khi chuyển hướng.
vee

60

Một ví dụ điển hình về 307 Internal Redirecthành động là khi Google Chrome bắt gặp một cuộc gọi HTTP đến một miền mà nó biết là yêu cầu Bảo mật Giao thông nghiêm ngặt.

Trình duyệt chuyển hướng liền mạch, sử dụng cùng một phương thức như cuộc gọi ban đầu.

Chuyển hướng nội bộ HTST 307


2
Bạn có biết khi Google triển khai tính năng này không?
Tijme

2
Vâng, đây là nơi tôi đang thấy điều đó xảy ra - máy chủ của chúng tôi không gửi nó - trong chrome devtools có vẻ như nó chỉ là chrome thực hiện chuyển hướng bởi vì chúng tôi có tiêu đề Strict Transport Security
mike nelson

16

Sơ đồ

  • 301: chuyển hướng vĩnh viễn: URL đã cũ và cần được thay thế. Trình duyệt sẽ lưu trữ bộ đệm này.
    Ví dụ sử dụng: URL được chuyển từ /register-form.htmlsang signup-form.html.
    Phương thức sẽ thay đổi thành GET, theo RFC 7231: "Vì lý do lịch sử, tác nhân người dùng CÓ THỂ thay đổi phương thức yêu cầu từ POST sang GET cho yêu cầu tiếp theo."
  • 302: chuyển hướng tạm thời. Chỉ sử dụng cho khách hàng HTTP / 1.0. Mã trạng thái này không nên thay đổi phương thức, nhưng các trình duyệt vẫn làm điều đó. RFC nói: "Nhiều tác nhân người dùng tiền HTTP / 1.1 không hiểu [303]. Khi lo ngại về khả năng tương tác với các máy khách như vậy, mã trạng thái 302 có thể được sử dụng thay thế, vì hầu hết các tác nhân người dùng phản ứng với phản hồi 302 như được mô tả ở đây cho 303. " Tất nhiên, một số khách hàng có thể thực hiện nó theo thông số kỹ thuật, vì vậy nếu khả năng tương tác với các khách hàng cổ như vậy không phải là mối quan tâm thực sự, thì 303 tốt hơn cho kết quả nhất quán.
  • 303: chuyển hướng tạm thời, thay đổi phương thức thành GET.
    Ví dụ sử dụng: nếu trình duyệt đã gửi POST đến /register.php, thì bây giờ tải (GET) /success.html.
  • 307: chuyển hướng tạm thời, lặp lại yêu cầu giống hệt nhau.
    Ví dụ sử dụng: nếu trình duyệt đã gửi POST đến /register.php, thì điều này sẽ cho nó làm lại POST tại /signup.php.
  • 308: chuyển hướng vĩnh viễn, lặp lại yêu cầu giống hệt nhau. Trong đó 307 là đối tác "không thay đổi phương thức" của 303, trạng thái 308 này là đối tác "không thay đổi phương thức" của 301.

RFC 7231 (từ 2014) rất dễ đọc và không quá dài dòng. Nếu bạn muốn biết câu trả lời chính xác, thì nên đọc. Một số câu trả lời khác sử dụng RFC 2616 từ năm 1999, nhưng không có gì thay đổi.

RFC 7238 chỉ định trạng thái 308. Nó được coi là thử nghiệm, nhưng nó đã được hỗ trợ bởi tất cả các trình duyệt chính trong năm 2016.


302 không được phản đối.
Julian Reschke

@JulianReschke Wikipedia cho biết "302 đã được thay thế bởi 303 và 307." Có thể đó là vì tôi không phải là người bản ngữ, nhưng đối với tôi (trong bối cảnh này) thay thế và phản đối có nghĩa giống nhau: sử dụng 303 hoặc 307, nhưng không phải 302. Tôi có đọc nhầm không?
Luc

Điều sai lầm là giả định rằng Wikipedia có tiếng nói về nó. Nếu 302 không được chấp nhận, HTTP sẽ nói như vậy.
Julian Reschke

@JulianReschke Đủ công bằng, tôi đã lấy nguồn và waddayaknow? Bạn hoàn toàn đúng. RFC thực sự rất dễ hiểu, và thực sự họ thậm chí còn đề xuất 302 trong một số điều kiện nhất định. Không có RFC "được cập nhật bởi" và "bị lỗi thời" được đề cập ở trên là về mã trạng thái, vì vậy tôi đoán tài liệu năm 1999 này thực sự là tài liệu mới nhất chúng tôi có về nó. Tôi sẽ cập nhật câu trả lời của tôi.
Luc

Những gì có liên quan là đăng ký mã trạng thái IANA, và do đó, trong trường hợp này, RFC 7231.
Julian Reschke

8

EXPECTED cho 302: redirect sử dụng cùng một phương thức yêu cầu POST trên NEW_URL

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

THỰC TẾ cho 302, 303: chuyển hướng phương thức yêu cầu từ POST sang GET trên 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)

THỰC TẾ cho 307: chuyển hướng sử dụng cùng một phương thức yêu cầu POST trên NEW_URL

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

2

302 là chuyển hướng tạm thời, được tạo bởi máy chủ trong khi 307 là phản hồi chuyển hướng nội bộ được tạo bởi trình duyệt. Chuyển hướng nội bộ có nghĩa là chuyển hướng được thực hiện tự động bởi trình duyệt trong nội bộ, về cơ bản trình duyệt thay đổi url đã nhập từ http sang https trong yêu cầu trước khi thực hiện yêu cầu nên yêu cầu kết nối không bảo mật không bao giờ được thực hiện với internet. Trình duyệt có thay đổi url thành https hay không phụ thuộc vào danh sách tải trước hsts được cài đặt sẵn với trình duyệt. Bạn cũng có thể thêm bất kỳ trang web nào hỗ trợ https vào danh sách bằng cách nhập tên miền vào danh sách tải trước hsts của trình duyệt của riêng bạn tại chrome: // net-i INTERNals / # hsts. Một số tên miền trang web khác có thể được thêm bởi chủ sở hữu của chúng để tải trước danh sách bằng cách điền vào biểu mẫu tại https://hstspreload.org/để nó được cài đặt sẵn trong trình duyệt cho mọi người dùng mặc dù tôi đề cập đến bạn cũng có thể làm đặc biệt cho chính mình.


Hãy để tôi giải thích với một ví dụ:
Tôi đã gửi yêu cầu tới http://www.pentesteracademy.com chỉ hỗ trợ https và tôi không có tên miền đó trong danh sách tải trước hsts của mình trên trình duyệt vì chủ sở hữu trang web chưa đăng ký cho nó để đi kèm với danh sách tải trước hsts được cài đặt sẵn. Yêu cầu NHẬN phiên bản không an toàn của trang web được chuyển hướng sang phiên bản bảo mật (xem tiêu đề http có tên là vị trí để phản hồi trong hình trên). Bây giờ tôi thêm trang web vào danh sách tải trước trình duyệt của riêng mình bằng cách thêm tên miền của nó vào biểu mẫu tên miền Thêm hsts tại chrome: // net-internals / # hsts, điều chỉnh danh sách tải trước cá nhân của tôi trên trình duyệt chrome của tôi. Hãy chắc chắn chọn bao gồm tên miền phụ cho Tùy chọn STS ở đó. Bây giờ chúng ta hãy xem yêu cầu và phản hồi cho cùng một trang web sau khi thêm nó vào danh sách tải trước hsts.yêu cầu và phản hồi tiêu đề



yêu cầu và phản hồi tiêu đề
bạn có thể thấy chuyển hướng nội bộ 307 ở đó trong các tiêu đề phản hồi, thực sự phản hồi này được tạo bởi trình duyệt của bạn chứ không phải bởi máy chủ.
Ngoài ra danh sách tải trước HSTS có thể giúp ngăn người dùng tiếp cận phiên bản trang web không an toàn vì chuyển hướng 302 dễ bị tấn công.
Hy vọng tôi phần nào giúp bạn hiểu thêm về chuyển hướng.


2

Ban đầu chỉ có 302

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

Ý tưởng là:

  • nếu bạn đang làm GETtại một địa điểm nào đó, bạn sẽ làm lại GETURL mới
  • nếu bạn đang làm POSTtại một địa điểm nào đó, bạn sẽ làm lại POSTURL mới
  • nếu bạn đang làm PUTtại một địa điểm nào đó, bạn sẽ làm lại PUTURL mới
  • nếu bạn đang làm DELETEtại một địa điểm nào đó, bạn sẽ làm lại DELETEURL mới
  • Vân vân

Thật không may, mọi trình duyệt đã làm sai. Khi nhận được một 302, họ sẽ luôn luôn chuyển sang GETtại URL mới, chứ không phải thử lại yêu cầu với cùng một động từ ( ví dụ , POST):

  • Khảm đã làm sai
  • Netscape đã sao chép các lỗi trong Khảm; vì vậy họ đã hiểu sai
  • Internet Explorer đã sao chép các lỗi trong Netscape; vì vậy họ đã hiểu sai

Nó trở thành thực tế sai.

Tất cả các trình duyệt đã 302sai. Vì vậy 303307đã được tạo ra.

| Phản hồi | Những trình duyệt nào nên làm | Những trình duyệt thực sự làm gì | | ------------------------ | ------------------------ --- | --------------------------- | | Tìm thấy 302 | Làm lại yêu cầu với url mới | NHẬN với url mới | | 303 Xem Khác | NHẬN với url mới | NHẬN với url mới | | 307 Chuyển hướng tạm thời | Làm lại yêu cầu với url mới | Làm lại yêu cầu với url mới |

Ở dạng biểu đồ

5 loại chuyển hướng khác nhau:

╔═══════════╤════════════════════════════════════════════════╗
║           │                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)    ║
╚═══════════╧════════════════════════╧═══════════════════════╝

Cách khác:

| 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

Ngoài ra, đối với quản trị viên máy chủ, điều quan trọng cần lưu ý là các trình duyệt có thể đưa ra lời nhắc cho người dùng nếu bạn sử dụng chuyển hướng 307.

Ví dụ *, Firefox và Opera sẽ yêu cầu người dùng cho phép chuyển hướng, trong khi Chrome, IE và Safari sẽ thực hiện chuyển hướng trong suốt.

* trên mỗi Bulletproof SSL và TLS (trang 192).


Điều đó chỉ đúng với các yêu cầu không an toàn, chẳng hạn như POST.
Julian Reschke

0

Trong một số trường hợp sử dụng, 307 người chuyển hướng có thể bị kẻ tấn công lạm dụng để tìm hiểu thông tin đăng nhập của nạn nhân.

Thông tin chi tiết có thể được tìm thấy trong phần 3.1 của Phân tích bảo mật chính thức toàn diện của OAuth 2.0 .

Các tác giả của bài viết trên đề nghị như sau:

Sửa chữa. Trái với cách diễn đạt hiện tại trong tiêu chuẩn OAuth, phương pháp chính xác của chuyển hướng không phải là một chi tiết triển khai mà cần thiết cho sự bảo mật của OAuth. Trong tiêu chuẩn HTTP ( RFC 7231 ), chỉ có chuyển hướng 303 được xác định một cách không tôn giáo để loại bỏ phần thân của yêu cầu POST HTTP. Tất cả các mã trạng thái chuyển hướng HTTP khác, bao gồm 302 được sử dụng phổ biến nhất, để lại cho trình duyệt tùy chọn duy trì yêu cầu POST và dữ liệu biểu mẫu. Trong thực tế, các trình duyệt thường viết lại thành một yêu cầu GET, do đó loại bỏ dữ liệu biểu mẫu, ngoại trừ 307 chuyển hướng. Do đó, tiêu chuẩn OAuth cần yêu cầu chuyển hướng 303 cho các bước được đề cập ở trên để khắc phục vấn đề này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.