Kegagalan Login RESTful: Return 401 atau Custom Response

103

Ini adalah pertanyaan konseptual.

Saya memiliki aplikasi klien (seluler) yang perlu mendukung tindakan login terhadap layanan web RESTful. Karena layanan web RESTful, ini berarti klien menerima nama pengguna / kata sandi dari pengguna, memverifikasi nama pengguna / kata sandi itu dengan layanan, dan kemudian hanya mengingat untuk mengirim nama pengguna / kata sandi itu dengan semua permintaan berikutnya.

Semua tanggapan lain di layanan web ini disediakan dalam format JSON.

Pertanyaannya adalah, ketika saya menanyakan layanan web hanya untuk mengetahui apakah nama pengguna / kata sandi yang diberikan valid, haruskah layanan web selalu merespons dengan data JSON yang memberi tahu saya berhasil atau tidak, atau haruskah mengembalikan HTTP 200 dengan kredensial yang baik dan HTTP 401 tentang kredensial buruk.

Alasan saya bertanya adalah bahwa beberapa layanan RESTful lainnya menggunakan 401 untuk kredensial yang buruk bahkan ketika Anda hanya menanyakan apakah kredensial tersebut valid. Namun, pemahaman saya tentang 401 tanggapan adalah bahwa mereka mewakili sumber daya yang seharusnya tidak dapat Anda akses tanpa kredensial yang valid. Tetapi sumber daya login HARUS dapat diakses oleh siapa pun karena seluruh tujuan sumber daya login adalah untuk memberi tahu Anda apakah kredensial Anda valid.

Dengan kata lain, menurut saya permintaan seperti:

myservice.com/this/is/a/user/action 

harus mengembalikan 401 jika kredensial buruk diberikan. Tapi permintaan seperti:

myservice.com/are/these/credentials/valid

tidak boleh mengembalikan 401 karena URL (permintaan) tersebut diotorisasi dengan atau tanpa kredensial yang valid.

Saya ingin mendengar beberapa pendapat yang dapat dibenarkan tentang hal ini. Apa cara standar untuk menangani ini, dan apakah cara standar penanganan ini sesuai secara logis?

Matt
sumber

Jawaban:

128

Pertama. 401 adalah kode respon yang tepat untuk dikirim ketika login gagal telah terjadi.

401 Unauthorized Mirip dengan 403 Forbidden, tetapi khusus untuk digunakan saat otentikasi diperlukan dan telah gagal atau belum disediakan. Responsnya harus menyertakan kolom header WWW-Authenticate yang berisi tantangan yang berlaku untuk sumber daya yang diminta.

Kebingungan Anda tentang, myservice.com/are/these/credentials/validmengirim kembali 401 ketika Anda baru saja melakukan pemeriksaan, menurut saya didasarkan pada fakta bahwa melakukan permintaan boolean di REST sering kali salah oleh kendala RESTful. Setiap permintaan harus mengembalikan sumber daya. Melakukan pertanyaan boolean dalam layanan RESTful adalah pekerjaan yang licin hingga RPC.

Sekarang saya tidak tahu bagaimana layanan yang Anda lihat berperilaku. Tetapi cara yang baik untuk menyelesaikan ini adalah dengan memiliki sesuatu seperti objek Akun, yang Anda coba DAPATKAN. Jika kredensial Anda benar, Anda akan mendapatkan objek Akun, jika Anda tidak ingin menyia-nyiakan bandwidth hanya untuk "memeriksa" Anda dapat melakukan HEAD pada sumber yang sama.

Objek Akun juga merupakan tempat yang bagus untuk menyimpan semua nilai boolean yang mengganggu yang sebaliknya akan sulit untuk membuat sumber daya individual.

Ulama
sumber
2
Poin Anda tentang pengembalian sumber daya tampaknya valid dan mungkin itu langkah yang tepat di sini. Mengenai pernyataan bahwa 401 adalah respons yang tepat, saya menghargai beberapa penjelasan di sana. Saya telah membaca spesifikasi HTTP, seperti yang telah Anda sertakan di sini, tetapi bagi saya itu tidak dibaca sebagai konfirmasi langsung dan jelas dari pernyataan Anda. Yakni, otentikasi TIDAK diperlukan untuk menanyakan tentang validitas kredensial - namun apa yang Anda sertakan mengatakan "khusus untuk digunakan ketika otentikasi diperlukan."
Matt
3
Cara Anda memandangnya benar. Anda tidak perlu diautentikasi untuk dapat meminta objek Akun Anda. Tetapi Anda harus berhasil mengautentikasi agar dapat menerima sumber daya, dan di situlah authentication is required and has failed or has not yet been providedberlaku, karena Anda tidak meminta validitas kredensial, tetapi untuk sumber daya tertentu berdasarkan kredensial yang Anda berikan.
Ulama
2
Saya mengerti mengapa Anda ingin melakukan "panggilan-periksa" dan untuk itu, saya akan tetap mempromosikan 401 sebagai kode respons yang sesuai untuk autentikasi yang gagal, meskipun panggilan tersebut tidak memerlukan autentikasi agar dapat dipanggil. A 204 No Content mungkin juga cocok, tetapi terasa agak ambigu.
Ulama
4
Saya tidak melihat bagaimana ini bisa benar, kecuali Anda menggunakan otentikasi Basic atau Digest. Sesuai bagian yang dikutip dari spesifikasi: "Respons harus menyertakan WWW-Authenticate" - dan jika Anda merujuk ke bagian 14.47: "Proses otentikasi akses HTTP dijelaskan dalam" HTTP Authentication: Basic and Digest Access Authentication ". Ini berarti bagi saya bahwa 401 tidak sesuai jika Anda menggunakan validasi email / sandi biasa.
Jonah
1
Saya pikir ini mungkin salah, saya telah menerapkan klien baik web maupun seluler dan saya mencegat 401 untuk mengalihkan ke layar masuk. Tetapi ketika seseorang sudah berada di layar login dan mengirimkan kredensial yang salah, responsnya juga memiliki 401 dan akan mencoba mengalihkan lagi. Harus ada kode status yang berbeda untuk upaya yang gagal untuk mendapatkan otentikasi ketika mencoba secara eksplisit. Mungkin permintaan yang buruk atau bahkan kesalahan server?
Japheth Ongeri - inkalimeva
27

401 harus dikirim hanya jika permintaan membutuhkan kolom header otorisasi dan otorisasi gagal. Karena API Login tidak memerlukan otorisasi, maka 401 adalah kode kesalahan yang salah menurut saya

Sesuai standar di sini https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 Tidak Resmi

Permintaan tersebut membutuhkan otentikasi pengguna. Respons HARUS menyertakan kolom header WWW-Authenticate (bagian 14.47) yang berisi tantangan yang berlaku untuk sumber daya yang diminta. Klien DAPAT mengulangi permintaan dengan bidang header Otorisasi yang sesuai (bagian 14.8). Jika permintaan sudah menyertakan kredensial Otorisasi, maka respons 401 menunjukkan bahwa otorisasi telah ditolak untuk kredensial tersebut. Jika respons 401 berisi tantangan yang sama dengan respons sebelumnya, dan agen pengguna telah mencoba autentikasi setidaknya satu kali, pengguna HARUS diberikan entitas yang diberikan dalam respons, karena entitas tersebut mungkin menyertakan informasi diagnostik yang relevan. Otentikasi akses HTTP dijelaskan dalam "Otentikasi HTTP: Otentikasi Akses Dasar dan Intisari" [43]. *

vinksharma
sumber
8
Saya setuju dengan Anda tentang hal ini, tetapi apa status tanggapan alternatif untuk dikirim? Saya telah menerapkan klien baik web maupun seluler dan saya mencegat 401 untuk mengalihkan ke layar login. Tetapi ketika seseorang sudah berada di layar login dan mengirimkan kredensial yang salah, responsnya juga memiliki 401 dan akan mencoba mengalihkan lagi ... apa yang akan Anda lakukan?
Japheth Ongeri - inkalimeva
0

Kembalikan 409 dengan pesan kesalahan yang benar.

kereta udang
sumber