Saya sedang membangun API yang tenang yang menggunakan token JWT untuk otentikasi pengguna (dikeluarkan oleh login
titik akhir dan mengirim semua header setelah itu), dan token harus di-refresh setelah jumlah waktu yang tetap (menggunakan renew
titik akhir, yang mengembalikan token yang diperbarui ).
Mungkin saja sesi API pengguna menjadi tidak valid sebelum token berakhir, karenanya semua titik akhir saya mulai dengan memeriksa bahwa: 1) token masih valid dan 2) sesi pengguna masih valid. Tidak ada cara untuk membatalkan token secara langsung, karena klien menyimpannya secara lokal.
Oleh karena itu, semua titik akhir saya harus memberi sinyal kepada klien saya tentang dua kondisi yang mungkin: 1) bahwa sudah waktunya untuk memperbarui token atau 2) bahwa sesi menjadi tidak valid, dan mereka tidak lagi diizinkan untuk mengakses sistem. Saya dapat memikirkan dua alternatif untuk titik akhir saya untuk memberi sinyal kepada klien mereka ketika salah satu dari dua kondisi terjadi (asumsikan bahwa klien dapat disesuaikan dengan salah satu opsi):
- Kembalikan kode http 401 (tidak resmi) jika sesi menjadi tidak valid atau kembalikan kode 412 (prasyarat gagal) ketika token telah kedaluwarsa dan sudah waktunya untuk memanggil
renew
titik akhir, yang akan mengembalikan kode 200 (ok). - Kembalikan 401 untuk memberi isyarat bahwa sesi tidak valid atau token telah kedaluwarsa. Dalam hal ini klien akan segera memanggil
renew
titik akhir, jika mengembalikan 200 maka token di-refresh, tetapi jikarenew
juga mengembalikan 401 maka itu berarti bahwa klien keluar dari sistem.
Manakah dari dua alternatif di atas yang akan Anda rekomendasikan? Yang mana yang lebih standar, lebih sederhana untuk dipahami, dan / atau lebih tenang? Atau apakah Anda akan merekomendasikan pendekatan yang berbeda sama sekali? Apakah Anda melihat masalah yang jelas atau risiko keamanan dengan salah satu opsi? Poin tambahan jika jawaban Anda menyertakan referensi eksternal yang mendukung pendapat Anda.
MEMPERBARUI
Guys, tolong fokus pada pertanyaan sebenarnya - mana dari dua alternatif kode http untuk menandakan perpanjangan / sesi invalidasi adalah yang terbaik? Jangan pedulikan fakta bahwa sistem saya menggunakan JWT dan sesi sisi server, itu adalah kekhasan API saya untuk aturan bisnis yang sangat spesifik, dan bukan bagian yang saya cari bantuannya;)
sumber
Jawaban:
Ini terdengar seperti kasus otentikasi versus otorisasi .
JWT adalah klaim yang ditandatangani secara kriptografis tentang pencetus permintaan. JWT mungkin berisi klaim seperti "Permintaan ini untuk pengguna X" dan "Pengguna X memiliki peran administrator". Mendapatkan dan memberikan bukti ini melalui kata sandi, tanda tangan, dan TLS adalah domain otentikasi - membuktikan bahwa Anda adalah siapa Anda sebenarnya.
Apa yang mereka klaim berarti ke server Anda - apa yang pengguna tertentu dan peran diizinkan untuk melakukan - adalah masalah otorisasi . Perbedaan antara keduanya dapat dijelaskan dengan dua skenario. Misalkan Bob ingin memasuki bagian penyimpanan terbatas di gudang perusahaannya, tetapi pertama-tama ia harus berurusan dengan seorang penjaga bernama Jim.
Skenario A - Otentikasi
Skenario B - Otorisasi
Waktu kedaluwarsa JWT adalah perangkat otentikasi yang digunakan untuk mencegah orang lain mencuri mereka. Jika semua JWT Anda memiliki waktu kedaluwarsa lima menit, itu bukan masalah besar jika dicuri karena mereka dengan cepat menjadi tidak berguna. Namun, "kedaluwarsa sesi" aturan yang Anda diskusikan terdengar seperti masalah otorisasi. Beberapa perubahan status berarti bahwa pengguna X tidak lagi diizinkan untuk melakukan sesuatu yang sebelumnya dapat mereka lakukan. Misalnya, pengguna Bob mungkin telah dipecat - tidak masalah bahwa lencananya mengatakan dia adalah Bob lagi, karena hanya menjadi Bob tidak lagi memberinya wewenang dengan perusahaan.
Dua kasus ini memiliki kode respons HTTP berbeda:
401 Unauthorized
dan403 Forbidden
. Kode 401 yang sayangnya bernama untuk masalah otentikasi seperti kredensial hilang, kedaluwarsa, atau dicabut. 403 untuk otorisasi, di mana server tahu persis siapa Anda, tetapi Anda tidak diizinkan melakukan hal yang ingin Anda lakukan. Dalam hal akun pengguna dihapus, mencoba melakukan sesuatu dengan JWT di titik akhir akan menghasilkan respons Terlarang 403. Namun, jika JWT kedaluwarsa, hasil yang benar adalah 401 Tidak Resmi.Pola JWT yang umum adalah memiliki token "berumur panjang" dan "berumur pendek". Token berumur panjang disimpan pada klien seperti token berumur pendek, tetapi tokennya terbatas dan hanya digunakan dengan sistem otorisasi Anda untuk mendapatkan token berumur pendek. Token berumur panjang, seperti namanya, memiliki periode kedaluwarsa yang sangat panjang - Anda dapat menggunakannya untuk meminta token baru selama berhari-hari atau berminggu-minggu. Token berumur pendek adalah token yang Anda gambarkan, digunakan dengan waktu kedaluwarsa yang sangat singkat untuk berinteraksi dengan sistem Anda. Token berumur panjang berguna untuk mengimplementasikan fungsi Remember Me, jadi Anda tidak perlu memberikan kata sandi setiap lima menit untuk mendapatkan token baru yang berumur pendek.
Masalah "sesi tidak valid" yang Anda gambarkan terdengar mirip dengan mencoba membatalkan JWT yang berumur panjang, karena yang berumur pendek jarang disimpan di sisi server sedangkan yang berumur panjang dilacak jika mereka perlu dicabut. Dalam sistem seperti itu, upaya untuk memperoleh kredensial dengan token berumur panjang yang dicabut akan menghasilkan 401 Tidak Sah, karena pengguna mungkin secara teknis dapat memperoleh kredensial tetapi token yang mereka gunakan tidak cocok untuk tugas tersebut. Kemudian ketika pengguna mencoba memperoleh token baru yang berumur panjang menggunakan nama pengguna dan kata sandi mereka, sistem dapat merespons dengan 403 Forbidden jika mereka dikeluarkan dari sistem.
sumber
Sesi API Anda adalah hal yang seharusnya tidak ada di dunia yang tenang sama sekali. Operasi yang tenang seharusnya tanpa kewarganegaraan, sesi berisi keadaan dan dengan demikian tidak memiliki tempat di dunia yang tenang.
JWT harus menjadi satu-satunya cara Anda untuk menentukan apakah pengguna masih memenuhi syarat untuk mengakses titik akhir atau tidak. Sesi seharusnya sama sekali tidak memainkan peran di dalamnya. Jika ya, Anda tidak memiliki API yang tenang.
Ketika Anda menghilangkan sesi sama sekali, yang jika Anda bertujuan untuk RESTful API yang harus Anda lakukan, dan hanya menggunakan JWT sebagai faktor autentikasi, pengguna entah berwenang untuk menggunakan titik akhir Anda atau tidak - dalam hal ini
401 Unauthorized
kode respons sesuai - dan harus menghubungirenew
titik akhir dengangrant_type=refresh_token
atau identifikasi pembaruan apa pun yang Anda gunakan.Memperbarui:
Dari komentar sepertinya aliran validasi JWT yang Anda gunakan saat ini tidak benar. Validasi seharusnya terlihat seperti ini:
Server,,
RESTful API
harus memeriksa validitas token yang dikirim sebagai Otorisasi. Itu bukan tanggung jawabClient
. Sepertinya Anda saat ini tidak melakukan ini. Laksanakan verifikasi JWT dengan cara ini dan Anda tidak perlu sesi sama sekali.sumber
Jadi, saya akui bahwa tidak masuk akal bagi saya untuk khawatir tentang pendekatan mana yang paling TENANG ketika Anda sudah melanggar konvensi REST dengan sesi ini, tapi saya mengerti memuaskan kebutuhan bisnis Anda.
Dari sudut pandang REST, klien diautentikasi, atau tidak. Arsitekturnya tidak terlalu peduli mengapa (itu menyuntikkan keadaan yang tidak perlu), jadi untuk menjawab pertanyaan utama Anda, saya tidak akan memiliki titik akhir yang diperbarui sama sekali. Klien yang masuk hanya akan selalu mengirim JWT mereka dan server selalu memvalidasinya dan menerima dengan mengirim kode Sukses yang sesuai berdasarkan tindakan 200, 201, dll.) Atau menolak dengan 401 atau 403 yang sesuai.
Sekarang, JWT akan dikaitkan dengan semacam akun. Akun itu mungkin dikunci atau dibatasi atau apa pun, dan token itu sendiri mungkin valid tetapi tindakannya masih ditolak di tempat lain. Jika kasusnya adalah bahwa akun pengguna dikunci karena aturan bisnis, maka itu masih 401 atau 403 tergantung pada seberapa banyak info yang ingin Anda berikan kepada klien (bisnis yang berbeda memiliki pendapat berbeda tentang itu).
Akhirnya, jika Anda menyatakan bahwa akun tersebut mungkin tidak dikunci dan valid tetapi JWT hanya perlu dicabut, maka saya akan MASIH tetap dengan 401 atau 403 dan mempertahankan sesuatu seperti Daftar Pencabutan Sertifikat JWT yang tidak valid yang dapat Anda masukkan ke dalamnya. , asalkan membersihkan sendiri ketika JWT akan kedaluwarsa (kebanyakan database memiliki cara untuk melakukan itu atau Anda dapat memiliki acara dalam kode aplikasi).
sumber