Apa kode status HTTP yang benar saat mengarahkan ke halaman login?

133

Ketika pengguna tidak masuk dan mencoba mengakses halaman yang memerlukan login, apa kode status HTTP yang benar untuk pengalihan ke halaman login?

Saya bertanya karena tidak ada kode respons 3xx yang ditetapkan oleh W3C yang tampaknya sesuai dengan persyaratan:

10.3.1 300 Pilihan Ganda

Sumber daya yang diminta sesuai dengan salah satu dari sekumpulan representasi, masing-masing dengan lokasi spesifiknya sendiri, dan informasi negosiasi yang digerakkan oleh agen (bagian 12) disediakan sehingga pengguna (atau agen pengguna) dapat memilih representasi yang diinginkan dan mengarahkan kembali minta ke lokasi itu.

Kecuali itu permintaan HEAD, respons HARUS menyertakan entitas yang berisi daftar karakteristik sumber daya dan lokasi dari mana pengguna atau agen pengguna dapat memilih yang paling tepat. Format entitas ditentukan oleh jenis media yang diberikan di bidang header Jenis Konten. Tergantung pada format dan kemampuan

agen pengguna, pemilihan pilihan yang paling tepat DAPAT dilakukan secara otomatis. Namun, spesifikasi ini tidak menentukan standar apa pun untuk pemilihan otomatis semacam itu.

Jika server memiliki pilihan pilihan representasi, itu HARUS menyertakan URI spesifik untuk representasi di bidang Lokasi; agen pengguna DAPAT menggunakan nilai bidang Lokasi untuk pengalihan otomatis. Respons ini dapat disimpan kecuali diminta sebaliknya.

10.3.2 301 Dipindahkan Secara Permanen

Sumber daya yang diminta telah diberi URI permanen baru dan referensi di masa mendatang untuk sumber daya ini HARUS menggunakan salah satu URI yang dikembalikan. Klien dengan kemampuan pengeditan tautan harus secara otomatis menautkan kembali referensi ke URI-Permintaan ke satu atau lebih dari referensi baru yang dikembalikan oleh server, jika memungkinkan. Respons ini dapat disimpan kecuali diminta sebaliknya.

URI permanen baru HARUS diberikan oleh bidang Lokasi dalam respons. Kecuali jika metode permintaan adalah KEPALA, entitas respon HARUS berisi catatan hiperteks pendek dengan hyperlink ke URI baru.

Jika kode status 301 diterima sebagai tanggapan terhadap permintaan selain GET atau HEAD, agen pengguna TIDAK HARUS mengarahkan permintaan kecuali kecuali dapat dikonfirmasi oleh pengguna, karena ini dapat mengubah kondisi di mana permintaan itu dikeluarkan.

  Note: When automatically redirecting a POST request after
  receiving a 301 status code, some existing HTTP/1.0 user agents
  will erroneously change it into a GET request.

10.3.3 302 Ditemukan

Sumber daya yang diminta tinggal sementara di bawah URI yang berbeda. Karena pengalihan mungkin kadang-kadang diubah, klien HARUS terus menggunakan Request-URI untuk permintaan di masa mendatang. Respons ini hanya dapat di-cache jika ditunjukkan oleh bidang header Kontrol-Cache atau Kedaluwarsa.

URI sementara HARUS diberikan oleh bidang Lokasi dalam respons. Kecuali jika metode permintaan adalah KEPALA, entitas respon HARUS berisi catatan hiperteks pendek dengan hyperlink ke URI baru.

Jika kode status 302 diterima sebagai respons terhadap permintaan selain GET atau HEAD, agen pengguna TIDAK HARUS mengarahkan permintaan kecuali kecuali dapat dikonfirmasi oleh pengguna, karena ini dapat mengubah kondisi di mana permintaan itu dikeluarkan.

  Note: RFC 1945 and RFC 2068 specify that the client is not allowed
  to change the method on the redirected request.  However, most
  existing user agent implementations treat 302 as if it

adalah respons 303, melakukan GET pada nilai bidang 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.

10.3.4 303 Lihat Lainnya

Respons terhadap permintaan dapat ditemukan di bawah URI yang berbeda dan HARUS diambil menggunakan metode GET pada sumber daya itu. Metode ini ada terutama untuk memungkinkan output dari skrip yang diaktifkan POST untuk mengarahkan agen pengguna ke sumber daya yang dipilih. URI baru bukan referensi pengganti untuk sumber daya yang diminta semula. Respons 303 TIDAK HARUS di-cache, tetapi respons terhadap permintaan kedua (dialihkan) mungkin dapat di-cache.

URI yang berbeda HARUS diberikan oleh bidang Lokasi dalam respons. Kecuali jika metode permintaan adalah KEPALA, entitas respon HARUS berisi catatan hiperteks pendek dengan hyperlink ke URI baru.

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
  status. When interoperability with such clients is a concern, the
  302 status code may be used instead, since most user agents react
  to a 302 response as described here for 303.

10.3.5 304 Tidak Dimodifikasi

Jika klien telah melakukan permintaan GET bersyarat dan akses diizinkan, tetapi dokumen belum dimodifikasi, server HARUS merespons dengan kode status ini. Respons 304 HARUS TIDAK mengandung badan pesan, dan dengan demikian selalu diakhiri oleh baris kosong pertama setelah bidang header.

Responsnya HARUS mencakup bidang tajuk berikut:

  - Date, unless its omission is required by section 14.18.1 If a

server asal clockless mematuhi aturan-aturan ini, dan proksi dan klien menambahkan Tanggal mereka sendiri ke setiap respons yang diterima tanpa satu (sebagaimana telah ditentukan oleh [RFC 2068], bagian 14.19), cache akan beroperasi dengan benar.

  - ETag and/or Content-Location, if the header would have been sent
    in a 200 response to the same request
  - Expires, Cache-Control, and/or Vary, if the field-value might
    differ from that sent in any previous response for the same
    variant If the conditional GET used a strong cache validator (see

bagian 13.3.3), respons TIDAK HARUS menyertakan header entitas lainnya. Jika tidak (yaitu, GET bersyarat menggunakan validator yang lemah), respons TIDAK HARUS menyertakan header entitas lainnya; ini mencegah inkonsistensi antara badan entitas yang di-cache dan header yang diperbarui.

Jika respons 304 menunjukkan entitas yang saat ini tidak di-cache, maka cache HARUS mengabaikan respons dan ulangi permintaan tanpa persyaratan.

Jika cache menggunakan respons 304 yang diterima untuk memperbarui entri cache, cache HARUS memperbarui entri untuk mencerminkan nilai bidang baru apa pun yang diberikan dalam respons.

10.3.6 305 Gunakan Proxy

Sumber daya yang diminta HARUS diakses melalui proxy yang diberikan oleh bidang Lokasi. Bidang Lokasi memberikan URI proxy. Penerima diharapkan mengulang permintaan tunggal ini melalui proxy. 305 tanggapan HARUS dihasilkan oleh server asal.

  Note: RFC 2068 was not clear that 305 was intended to redirect a
  single request, and to be generated by origin servers only.  Not
  observing these limitations has significant security consequences.

10.3.7 306 (Tidak digunakan)

306 kode status digunakan dalam versi spesifikasi sebelumnya, tidak lagi digunakan, dan kode dicadangkan.

10.3.8 307 Redirect Sementara

Sumber daya yang diminta tinggal sementara di bawah URI yang berbeda. Karena pengalihan MUNGKIN diubah pada kesempatan, klien HARUS terus menggunakan Request-URI untuk permintaan di masa depan. Respons ini hanya dapat di-cache jika ditunjukkan oleh bidang header Kontrol-Cache atau Kedaluwarsa.

URI sementara HARUS diberikan oleh bidang Lokasi dalam respons. Kecuali jika metode permintaan adalah HEAD, entitas dari respons HARUS berisi catatan hiperteks pendek dengan hyperlink ke URI baru, karena banyak agen pengguna pra-HTTP / 1.1 tidak memahami status 307. Oleh karena itu, catatan HARUS berisi informasi yang diperlukan bagi pengguna untuk mengulangi permintaan asli pada URI baru.

Jika kode status 307 diterima sebagai tanggapan terhadap permintaan selain GET atau HEAD, agen pengguna TIDAK HARUS mengarahkan permintaan kecuali kecuali dapat dikonfirmasi oleh pengguna, karena ini dapat mengubah kondisi di mana permintaan itu dikeluarkan.

Saya menggunakan 302 untuk saat ini, sampai aku menemukan yang jawaban yang benar.

Pembaruan & kesimpulan:

HTTP 302 lebih baik karena diketahui memiliki kompatibilitas terbaik dengan klien / browser.

Vidar Vestnes
sumber
1
Saya akan mengatakan benar-benar dengan cara buku akan mengembalikan 401 dan halaman login tanpa arahan, tapi saya tidak yakin apa pilihan Anda.
Nick Craver
1
@Tidak bagus, tapi saya akan takut efek samping dari itu jika saya membangun sistem login klasik.
Pekka
1
@Pekka - Sepenuhnya setuju, ini tergantung pada platform apa ini mengenai bagaimana semua itu dapat ditangani dengan bersih, juga jika itu intranet vs internet ikut bermain saya percaya ... Anda biasanya melakukan otentikasi dengan cara yang berbeda pada intranet, Setidaknya dalam pengalaman saya.
Nick Craver
@Nick With 401 "Responsnya HARUS menyertakan bidang header WWW-Authenticate" - Bagaimana saya bisa menggabungkan ini dengan database MySQL? Bukankah AuthType Basic dan Digest terbatas pada file konfigurasi apache seperti .htpassword dll ...?
Vidar Vestnes
Saya ingin halaman login khusus, bukan dialog browser dasar yang meminta nama pengguna dan kata sandi ...
Vidar Vestnes

Jawaban:

66

Saya akan mengatakan 303 lihat lainnya 302 Ditemukan:

Sumber daya yang diminta tinggal sementara di bawah URI yang berbeda. Karena pengalihan mungkin kadang-kadang diubah , klien HARUS terus menggunakan Request-URI untuk permintaan di masa mendatang. Respons ini hanya dapat di-cache jika ditunjukkan oleh bidang header Kontrol-Cache atau Kedaluwarsa.

cocok dengan halaman login paling dekat menurut saya. Saya awalnya mempertimbangkan 303 see otheryang akan bekerja dengan baik. Setelah beberapa pemikiran, saya akan mengatakan 302 Foundlebih pas karena sumber daya yang diminta itu ditemukan, ada saja halaman lain untuk pergi melalui sebelum dapat diakses. Responsnya tidak di-cache secara default yang juga bagus.

Pekka
sumber
4
Saya setuju, tetapi saya pikir 302 Found menunjukkan bahwa sumber itu ditemukan, tepat di bawah url lain. Ex. Saya ingin se / my-messages / jawaban server dengan 302 karena "hari ini" pesan saya berada di "/ login /" (bukan "/ messages /") ... Saya menggunakan 302, tetapi saya tidak merasa konteksnya adalah 100% cocok. Karena halaman login adalah sumber yang berbeda dan tidak memiliki konten yang sama seperti yang diminta.
Vidar Vestnes
2
@PHP_Jedi benar. 303 mungkin lebih tepat dari sudut pandang itu. Namun, 302 lebih dapat diandalkan dalam hal kompatibilitas klien.
Pekka
1
Yap, saya berpikir bahwa 303 mungkin lebih sesuai dengan konteks karena menyatakan "Respons terhadap permintaan dapat ditemukan di bawah URI yang berbeda". Ini memberitahu saya bahwa bukan sumber itu sendiri yang dapat ditemukan di URI lain, tetapi hanya respons terhadap permintaan ini.
Vidar Vestnes
3
@PHP_Jedi Saya tidak yakin apakah perlu menghabiskan banyak waktu dalam hal ini. Baik klien dan server di dunia http harus sangat liberal dan toleran terhadap kesalahan, jadi tidak akan ada perbedaan nyata apakah Anda menggunakan 302atau 303, kecuali yang 302lebih dikenal. Saya menemukan tingkat detail yang terpuji dan selalu baik untuk memperbaikinya, tetapi terlalu banyak usaha mungkin sia-sia di bidang khusus ini.
Pekka
28
FYI: Google mengeluarkan 302s
David Murdoch
51

Ini adalah penyalahgunaan mekanisme pengalihan HTTP. Jika pengguna tidak diotorisasi maka aplikasi Anda harus kembali 401 Unauthorized. Dalam hal pengguna diotorisasi tetapi tidak memiliki akses ke sumber daya yang diminta maka 403 Forbiddenharus dikembalikan.

Anda harus melakukan redirect di sisi klien, misalnya dengan javascript. kode status untuk pengalihan karena otorisasi yang diperlukan tidak ada . Menggunakan 30x untuk ini tidak sesuai dengan HTTP.

Cara Berpikir Tentang Kode Status HTTP oleh Mark Nottingham

401 Tidak Resmi memicu mekanisme otentikasi permintaan HTTP.

401 Unauthorizedkode status memerlukan keberadaan WWW-Authenticatetajuk yang mendukung berbagai jenis otentikasi:

Otentikasi WWW: <type> realm = <realm>

Bearer, OAuth, Basic, Intisari, Cookie, dll

filip26
sumber
20
A 401 mungkin tidak sesuai dalam beberapa kasus sebagai A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field( RFC ), dan tidak semua sistem login menggunakan header itu.
starbeamrainbowlabs
6
Misalkan Anda me-refresh halaman yang dilindungi; javascript sisi klien tidak akan memiliki perubahan untuk dipanggil, dan browser akan memunculkan jendela login alih-alih mengarahkan pengguna ke halaman login - jadi satu-satunya cara adalah menggunakan kode 30x.
Claude Brisson
2
Golang tidak dapat menggunakan 401 untuk pengalihan. Itu berarti kita harus menggunakan 30 * untuk pengalihan.
EIMEI
4
@EIMEI mengikuti alasan Anda, jika bahasa atau perpustakaan lain memaksa Anda untuk menggunakan 401, maka Internet akan hancur. Maksud saya adalah: apa yang Anda katakan menunjukkan masalah dengan Golang (meskipun saya merasa mengejutkan bahwa itu memiliki desain sedemikian rupa sehingga tidak mungkin mengirim 401-an!)
Greg
2
@starbeamrainbowlabs Ada opsi untuk Otentikasi HTTP berbasis Cookie sebagai opsi di header WWW-Authenticate. Lihat: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef
12

Saya pikir solusi yang sesuai adalah tajuk HTTP 401 (Tidak Diotorisasi).

http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

Tujuan dari tajuk ini persis seperti ini. Tetapi, alih-alih mengarahkan ulang ke halaman login, proses yang benar adalah:

  • Pengguna yang tidak login mencoba mengakses halaman yang dibatasi login.
  • sistem mengidentifikasi pengguna tidak login
  • sistem mengembalikan header HTTP 401, DAN menampilkan formulir login dalam respons yang sama (bukan redirect).

Ini adalah praktik yang baik, seperti menyediakan halaman 404 yang bermanfaat, dengan tautan sitemap, dan formulir pencarian misalnya.

Sampai jumpa.

Davis Peixoto
sumber
20
RFC menyatakan: "Respons tersebut HARUS menyertakan bidang header WWW-Otentikasi (bagian 14.46) yang berisi tantangan yang berlaku untuk sumber daya yang diminta." Respons 401 benar-benar hanya berlaku ketika menggunakan skema otentikasi HTTP.
bshacklett
4
Jika demikian, 403 akan lebih baik karena menyatakan bahwa akses itu hanya dilarang dan tajuk otorisasi tidak akan membantu
olanod
@ bshacklett WWW-Authenticate dapat digunakan bersama dengan banyak skema otentikasi (mis. Bearer, OAuth). Lihat developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… dan iana.org/assignments/http-authschemes/http-authschemes.xhtml
filip26
Ada konsep untuk Otentikasi HTTP berbasis Cookie sebagai opsi di header WWW-Authenticate. Lihat: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef