Apa perbedaan antara pengalihan 302 dan 307?


208

Apa perbedaan antara a 302 FOUNDdan a307 TEMPORARY REDIRECT respons HTTP HTTP?

Spek W3 tampaknya mengindikasikan bahwa keduanya digunakan untuk pengalihan sementara, dan tidak ada yang bisa di-cache kecuali jika respons secara khusus mengizinkannya.

Jawaban:


99

Perbedaannya menyangkut pengalihan POST, PUTdan DELETEpermintaan dan apa harapan server untuk perilaku agen pengguna ( RFC 2616):

Catatan: RFC 1945 dan RFC 2068 menentukan bahwa klien tidak diperbolehkan mengubah metode berdasarkan permintaan yang dialihkan. Namun, sebagian besar implementasi agen pengguna yang ada memperlakukan 302 seolah-olah itu adalah respons 303, melakukan GET pada nilai-lokasi Lokasi terlepas dari metode permintaan asli. Kode status 303 dan 307 telah ditambahkan untuk server yang ingin membuat jelas apa jenis reaksi yang diharapkan dari klien.

Baca juga artikel Wikipedia tentang kode pengalihan 30x .


Jadi, dari perspektif parser / agen / browser, kita bisa memperlakukan 302 dan 307 sebagai identik, kan? (Bagian kode yang sama persis dapat digunakan untuk menangani kedua kasus tanpa pembedaan lebih lanjut?)
Pacerier

Tidak - Anda dapat memperlakukan 302 dan 303 sebagai identik, tetapi 307 berbeda.
Quentin Skousen

@kkhugs, Tidak mungkin, browser 1.0 diperlukan untuk mendapatkan get-302 dengan cara yang sama seperti get-307 dilakukan di 1.1 browser. Browser 1.0 diperlukan untuk melakukan post-302 dengan cara yang sama seperti halnya mendapatkan-302, kecuali itu harus terlebih dahulu memerlukan konfirmasi pengguna untuk melanjutkan, dan metode harus posting.
Pacerier

Peramban 1.1 diperlukan untuk melakukan get-302 dengan cara yang sama seperti halnya mendapatkan-307.
Pacerier

161

307 muncul karena agen pengguna diadopsi sebagai de facto perilaku untuk mengambil permintaan POST yang menerima respons 302 dan mengirim permintaan GET ke header respons Lokasi.

Itu adalah perilaku yang salah - hanya 303 yang menyebabkan POST berubah menjadi GET. Agen pengguna harus (tetapi tidak) tetap menggunakan metode POST ketika meminta URL baru jika permintaan POST asli mengembalikan 302.

307 diperkenalkan untuk memungkinkan server menjelaskan kepada agen pengguna bahwa perubahan metode tidak boleh dilakukan oleh klien saat mengikuti header respons Lokasi.


3
Adakah contoh agen pengguna yang merespons secara tidak benar? Apakah biasanya persentase pengunjung yang sangat kecil?
goodguys_activate

6
@ makerofthings7 Semua peramban 302salah menangani . Chrome 30, IE10. Ini menjadi implementasi yang salah secara de facto ; itu tidak dapat diubah karena begitu banyak masalah situs web yang keliru mengeluarkan 302. Faktanya, ASP.net MVC salah mengeluarkan 302, tergantung pada fakta bahwa peramban menanganinya dengan tidak benar.
Ian Boyd

1
@IanBoyd Satu-satunya alasan kerangka kerja melakukan ini adalah karena 303juga diperkenalkan dengan 307spesifikasi HTTP 1.1 dan dengan demikian memungkinkan kompatibilitas dengan agen pengguna HTTP 1.0. Tentu saja, pertanyaan sebenarnya adalah apakah kita masih harus menangani agen pengguna HTTP 1.0 sekarang?
ewanm89

1
@ ewanm89 Tampaknya kerangka kerja itu dapat membuat metode respons yang dinamai dengan benar (misalnya Response.RedirectSeeOther), dan jika klien tidak 1,1 (misalnya GET /foo.html, GET /foo.html HTTP/1.0) maka keluarkan warisan 302.
Ian Boyd

Sepertinya 302 = 303 saat redirect.
vee

60

Contoh 307 Internal Redirecttindakan yang baik adalah ketika Google Chrome menemukan panggilan HTTP ke domain yang dikenalnya membutuhkan Keamanan Transportasi Ketat.

Peramban dialihkan dengan mulus, menggunakan metode yang sama dengan panggilan asli.

HTST 307 Pengalihan Internal


2
Apakah Anda tahu kapan Google menerapkan fitur ini?
Tijme

2
Ya di sinilah saya melihat hal itu terjadi - server kami tidak mengirimkannya - dalam devtools krom sepertinya memang seperti itu tetapi itu hanya chrome yang melakukan pengalihan karena kami memiliki tajuk Keamanan Transportasi Ketat
mike nelson

16

Diagram alir

  • 301: redirect permanen: URL sudah tua dan harus diganti. Browser akan men-cache ini.
    Contoh penggunaan: URL dipindahkan dari /register-form.htmlke signup-form.html.
    Metode ini akan berubah menjadi GET, sesuai RFC 7231: "Untuk alasan historis, agen pengguna DAPAT mengubah metode permintaan dari POST ke GET untuk permintaan selanjutnya."
  • 302: pengalihan sementara. Hanya digunakan untuk klien HTTP / 1.0.Kode status ini seharusnya tidak mengubah metode, tetapi browser tetap melakukannya. RFC mengatakan: "Banyak agen pengguna pra-HTTP / 1.1 tidak mengerti [303]. Ketika interoperabilitas dengan klien seperti itu menjadi perhatian, kode status 302 dapat digunakan sebagai gantinya, karena sebagian besar agen pengguna bereaksi terhadap respons 302 seperti dijelaskan di sini untuk 303. " Tentu saja, beberapa klien dapat mengimplementasikannya sesuai dengan spesifikasi, jadi jika interoperabilitas dengan klien kuno tersebut bukan masalah nyata, 303 lebih baik untuk hasil yang konsisten.
  • 303: redirect sementara, mengubah metode menjadi GET.
    Contoh penggunaan: jika browser mengirim POST /register.php, maka sekarang muat (GET) /success.html.
  • 307: pengalihan sementara, mengulangi permintaan secara identik.
    Contoh penggunaan: jika browser mengirim POST ke /register.php, maka ini memberitahukannya untuk mengulang POST di /signup.php.
  • 308: redirect permanen, mengulangi permintaan secara identik. Di mana 307 adalah mitra "tidak ada perubahan metode" dari 303, status 308 ini adalah mitra "tidak ada perubahan metode" dari 301.

RFC 7231 (dari 2014) sangat mudah dibaca dan tidak terlalu bertele-tele. Jika Anda ingin mengetahui jawaban pastinya, itu adalah bacaan yang disarankan. Beberapa jawaban lain menggunakan RFC 2616 dari tahun 1999, tetapi tidak ada yang berubah.

RFC 7238 menentukan status 308. Ini dianggap eksperimental, tetapi sudah didukung oleh semua browser utama pada tahun 2016.


302 tidak usang.
Julian Reschke

@JulianReschke Wikipedia mengatakan "302 telah digantikan oleh 303 dan 307." Mungkin itu karena saya bukan penutur asli, tetapi bagi saya (dalam konteks ini) digantikan dan ditinggalkan berarti sama: baik menggunakan 303 atau 307, tetapi tidak 302. Apakah saya salah membaca ini?
Luc

Apa yang salah adalah asumsi bahwa Wikipedia memiliki pendapat tentang hal itu. Jika 302 sudah tidak digunakan lagi, HTTP akan mengatakan demikian.
Julian Reschke

@JulianReschke Cukup adil, saya mengambil ke sumber dan waddayaknow? Anda sepenuhnya benar. RFC sebenarnya sangat dimengerti, dan bahkan mereka merekomendasikan 302 dalam kondisi tertentu. Tak satu pun dari "diperbarui oleh" dan "usang oleh" RFC yang disebutkan di atas adalah tentang kode status, jadi saya kira dokumen 1999 ini memang yang terbaru yang kami miliki. Saya akan memperbarui jawaban saya.
Luc

Yang relevan adalah registri kode status IANA, dan dengan demikian, dalam hal ini, RFC 7231.
Julian Reschke

8

EXPECTED for 302: redirect menggunakan metode permintaan yang sama POST pada NEW_URL

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

ACTUAL untuk 302, 303: redirect metode permintaan perubahan dari POST ke GET pada 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 for 307: redirect menggunakan metode permintaan yang sama POST pada NEW_URL

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

2

302 adalah redirect sementara, yang dihasilkan oleh server sedangkan 307 adalah respon redirect internal yang dihasilkan oleh browser. Pengalihan internal berarti pengalihan dilakukan secara otomatis oleh browser secara internal, pada dasarnya browser mengubah url yang dimasukkan dari http ke https di dapatkan permintaan dengan sendirinya sebelum membuat permintaan sehingga permintaan untuk koneksi yang tidak aman tidak pernah dilakukan ke internet. Apakah peramban akan mengubah url menjadi https atau tidak tergantung pada daftar pramuat pertama yang disertakan dengan peramban. Anda juga dapat menambahkan situs apa pun yang mendukung https ke daftar dengan memasukkan domain di daftar pramuat pertama peramban Anda sendiri yang ada di chrome: //net-internals/#hsts.Satu hal lagi domain situs web dapat ditambahkan oleh pemiliknya untuk memuat sebelumnya daftar dengan mengisi formulir di https://hstspreload.org/sehingga sudah terinstal di browser untuk setiap pengguna meskipun saya menyebutkan Anda dapat melakukannya terutama untuk diri sendiri.


Izinkan saya menjelaskan dengan sebuah contoh:
Saya membuat permintaan dapatkan ke http://www.pentesteracademy.com yang hanya mendukung https dan saya tidak memiliki domain itu di daftar pramuat pertama di browser saya karena pemilik situs belum mendaftar untuk itu datang dengan daftar preload hsts pra-instal MENDAPATKAN permintaan untuk versi situs yang tidak aman diarahkan ke versi aman (lihat header http bernama lokasi untuk itu sebagai respons pada gambar di atas). Sekarang saya menambahkan situs ke daftar pramuat browser saya sendiri dengan menambahkan domainnya di Tambahkan bentuk domain hsts di chrome: // net-internal / # hsts, yang mengubah daftar preload pribadi saya di browser chrome saya. Pastikan untuk memilih menyertakan subdomain untuk Opsi STS di sana. Mari kita lihat permintaan dan respons untuk situs web yang sama sekarang setelah menambahkannya ke daftar preload pertama.header permintaan dan respons



header permintaan dan respons
Anda dapat melihat redirect internal 307 di header respons, sebenarnya respons ini dihasilkan oleh browser Anda, bukan oleh server.
Juga daftar preload HSTS dapat membantu mencegah pengguna mencapai versi situs yang tidak aman karena 302 pengalihan rentan terhadap serangan mitm.
Semoga saya agak membantu Anda memahami lebih banyak tentang pengalihan.


2

Awalnya hanya ada 302

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

Idenya adalah:

  • jika Anda melakukan GETdi beberapa lokasi, Anda akan mengulangiGET ke URL baru
  • jika Anda melakukan POSTdi beberapa lokasi, Anda akan mengulangiPOST ke URL baru
  • jika Anda melakukan PUTdi beberapa lokasi, Anda akan mengulangiPUT ke URL baru
  • jika Anda melakukan DELETEdi beberapa lokasi, Anda akan mengulangiDELETE ke URL baru
  • dll

Sayangnya setiap browser melakukan kesalahan. Saat mendapatkan 302, mereka akan selalu beralih ke GETURL baru, alih-alih mencoba kembali permintaan dengan kata kerja yang sama ( misalnya , POST):

  • Mosaic melakukan kesalahan
  • Netscape menyalin bug di Mosaic; jadi mereka salah
  • Internet Explorer menyalin bug di Netscape; jadi mereka salah

Itu menjadi salah secara de facto .

Semua browser 302salah. Jadi 303dan 307diciptakan.

| Respon | Browser apa yang harus dilakukan | Apa yang sebenarnya dilakukan browser | | ------------------------ | ------------------------ --- | --------------------------- | | 302 Ditemukan | Ulangi permintaan dengan url baru | DAPATKAN dengan url baru | | 303 Lihat Lainnya | DAPATKAN dengan url baru | DAPATKAN dengan url baru | | 307 Redirect Sementara | Ulangi permintaan dengan url baru | Ulangi permintaan dengan url baru |

Dalam bentuk bagan

5 jenis pengalihan yang berbeda:

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

Kalau tidak:

| 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

Juga, untuk admin server, mungkin penting untuk dicatat bahwa browser dapat memberikan konfirmasi kepada pengguna jika Anda menggunakan 307 redirect.

Misalnya *, Firefox dan Opera akan meminta izin kepada pengguna untuk mengalihkan, sedangkan Chrome, IE dan Safari akan melakukan redirect secara transparan.

* per SSL Antipeluru dan TLS (halaman 192).


Itu hanya berlaku untuk permintaan yang tidak aman, seperti POST.
Julian Reschke

0

Dalam beberapa kasus penggunaan, 307 pengalihan mungkin disalahgunakan oleh penyerang untuk mempelajari kredensial korban.

Informasi lebih lanjut dapat ditemukan di bagian 3.1 dari Analisis Keamanan Formal Komprehensif OAuth 2.0 .

Para penulis makalah di atas menyarankan yang berikut:

Memperbaiki. Bertentangan dengan kata-kata saat ini dalam standar OAuth, metode redirect yang tepat bukanlah detail implementasi tetapi penting untuk keamanan OAuth. Dalam standar HTTP ( RFC 7231 ), hanya 303 redirect yang didefinisikan secara tidak religius untuk menjatuhkan isi permintaan HTTP POST. Semua kode status pengalihan HTTP lainnya, termasuk 302 yang paling umum digunakan, membiarkan browser opsi untuk menyimpan permintaan POST dan data formulir. Dalam praktiknya, browser biasanya menulis ulang permintaan GET, sehingga menjatuhkan data formulir, kecuali untuk 307 redirect. Oleh karena itu, standar OAuth harus memerlukan 303 redirect untuk langkah-langkah yang disebutkan di atas untuk memperbaiki masalah ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.