Otentikasi: penggunaan JWT vs sesi


122

Apa keuntungan menggunakan JWT dibandingkan sesi dalam situasi seperti otentikasi?

Apakah ini digunakan sebagai pendekatan mandiri atau digunakan dalam sesi?

Jawaban:


213

JWT tidak memiliki keuntungan dibandingkan menggunakan "sesi" per kata. JWT menyediakan cara untuk mempertahankan status sesi pada klien sebagai ganti melakukannya di server.

Apa yang orang sering maksud ketika menanyakan ini adalah "Apa manfaat menggunakan JWT dibandingkan menggunakan sesi sisi Server "

Dengan sesi sisi server, Anda harus menyimpan pengenal sesi dalam database, atau menyimpannya di memori dan memastikan bahwa klien selalu mengunjungi server yang sama. Keduanya memiliki kekurangan. Dalam kasus database (atau penyimpanan terpusat lainnya), ini menjadi hambatan dan hal yang harus dipertahankan - pada dasarnya kueri tambahan harus dilakukan dengan setiap permintaan.

Dengan solusi dalam memori, Anda membatasi penskalaan horizontal, dan sesi akan terpengaruh oleh masalah jaringan (klien menjelajah antara Wi-Fi dan data seluler, boot ulang server, dll.)

Memindahkan sesi ke klien berarti Anda menghapus ketergantungan pada sesi sisi server, tetapi menimbulkan serangkaian tantangannya sendiri.

  • Menyimpan token dengan aman
  • mengangkutnya dengan aman
  • Sesi JWT terkadang sulit dibatalkan.
  • Mempercayai klaim klien.

Masalah ini dibagikan oleh JWT dan mekanisme sesi sisi klien lainnya.

JWT secara khusus membahas yang terakhir ini. Mungkin membantu untuk memahami apa itu JWT:

Ini sedikit informasi. Untuk sesi pengguna, Anda dapat memasukkan nama pengguna dan waktu token kedaluwarsa. Tapi bisa dibayangkan apa saja, bahkan ID sesi atau seluruh profil pengguna. (Tolong jangan lakukan itu) Ia memiliki tanda tangan aman yang mencegah pihak jahat membuat token palsu (Anda memerlukan akses ke kunci pribadi server untuk menandatanganinya dan Anda dapat memverifikasi bahwa mereka tidak diubah setelah ditandatangani) Anda kirim mereka dengan setiap permintaan, seperti cookie atau AuthorizationHeader yang akan dikirim. Sebenarnya mereka biasanya dikirim di Authorizationheader HTTP tetapi menggunakan cookie juga baik-baik saja.

Token ditandatangani dan server dapat memverifikasi asalnya. Kami akan berasumsi bahwa server mempercayai kemampuannya sendiri untuk masuk dengan aman (Anda harus menggunakan pustaka standar: jangan mencoba melakukannya sendiri, dan amankan server dengan benar)

Mengenai masalah pengangkutan token secara aman, jawabannya biasanya mengirimkannya melalui saluran terenkripsi, biasanya httpS.

Mengenai penyimpanan token dengan aman di klien, Anda perlu memastikan bahwa orang jahat tidak bisa mendapatkannya. Ini (kebanyakan) berarti mencegah JS dari situs web yang buruk membaca token untuk mengirimkannya kembali kepada mereka. Ini dimitigasi dengan menggunakan strategi yang sama yang digunakan untuk mengurangi jenis serangan XSS lainnya.

Jika Anda memiliki kebutuhan untuk membatalkan JWT, pasti ada cara untuk mencapai hal ini. Menyimpan waktu per pengguna hanya untuk pengguna yang meminta "sesi lain dihentikan" adalah metode yang sangat efisien yang mungkin cukup baik. Jika aplikasi memerlukan pembatalan per sesi, maka ID sesi dapat dipertahankan dengan cara yang sama dan tabel "token yang dimatikan" masih dapat dipertahankan agar jauh lebih kecil daripada tabel pengguna penuh (Anda hanya perlu menyimpan catatan yang lebih baru dari token seumur hidup terlama yang diizinkan.) Jadi kemampuan untuk membatalkan token sebagian meniadakan manfaat sesi sisi klien di mana Anda harus mempertahankan status sesi terbunuh ini. Ini kemungkinan besar akan menjadi tabel yang jauh lebih kecil daripada tabel status sesi asli, sehingga pencarian masih lebih efisien.

Satu manfaat lain menggunakan token JWT adalah penerapannya cukup mudah menggunakan pustaka yang mungkin tersedia dalam semua bahasa yang mungkin Anda miliki. Ini juga benar-benar terpisah dari skema otentikasi pengguna awal Anda - jika Anda pindah ke sistem berbasis sidik jari, Anda tidak perlu membuat perubahan apa pun pada skema manajemen sesi.

Manfaat yang lebih halus: Karena JWT dapat membawa "informasi" dan ini dapat diakses oleh klien, Anda sekarang dapat mulai melakukan beberapa hal cerdas. Misalnya, ingatkan pengguna bahwa sesi mereka akan berakhir beberapa hari sebelum mereka keluar, memberi mereka opsi untuk mengautentikasi ulang, berdasarkan tanggal kedaluwarsa di token. Apapun yang bisa Anda bayangkan.

Jadi singkatnya: JWT menjawab beberapa pertanyaan dan kekurangan dari teknik sesi lainnya.

  1. Otentikasi "lebih murah" karena Anda dapat menghilangkan DB round trip (atau setidaknya memiliki tabel yang jauh lebih kecil untuk kueri!), Yang pada gilirannya memungkinkan skalabilitas horizontal.
  2. Klaim sisi klien yang tahan gangguan.

Meskipun JWT tidak menjawab masalah lain seperti penyimpanan atau pengangkutan yang aman, JWT tidak memperkenalkan masalah keamanan baru.

Ada banyak hal negatif di sekitar JWT, tetapi jika Anda menerapkan keamanan yang sama seperti yang Anda lakukan untuk jenis otentikasi lain, Anda akan baik-baik saja.

Satu catatan terakhir: Ini juga bukan Cookies vs Token. Cookies adalah mekanisme untuk menyimpan dan mengangkut bit informasi dan dapat digunakan untuk menyimpan dan mengangkut token JWT juga.


4
Perlu dicatat bahwa sesi sisi server juga tidak harus menyimpan informasi apa pun di server. Server dapat menggunakan klien sebagai toko dengan cara yang sama seperti JWT. Perbedaan sebenarnya adalah 1) menghindari aturan keamanan browser dengan meneruskan nilai sebagai header permintaan selain header cookie, dan 2) memiliki format standar dengan JWT.
Xeoncross

1
Apakah menurut Anda aman menyimpan jwt di penyimpanan lokal? Jika tidak, di manakah tempat yang aman untuk menyimpannya sehingga pengguna tetap login?
Jessica

1
Ya, penyimpanan lokal biasanya merupakan tempat paling tepat untuk menyimpannya di sisi klien. Anda perlu berurusan dengan XSS - Saya bukan ahli pemrograman web tetapi lihat Jawaban Ini stackoverflow.com/a/40376819/1810447 dan cari "Cara Melindungi Terhadap XSS"
Tahaan

1
Dalam komentar Anda, Anda tidak berbicara tentang solusi berbasis cache + token sesi. Bagi saya kedengarannya "lebih baik" daripada tabel JWT + "token terbunuh", karena dengan tabel "token terbunuh" ini, Anda tetap memerlukan akses DB, yang juga akan Anda miliki dengan sesi + cache (yang juga kecil). Dan mempertahankan JWT lebih menyakitkan untuk diterapkan daripada sesi bertahan, karena Anda perlu bermain dengan refresh_token (jadi dua token untuk dipertahankan) ... Setiap komentar akan sangat dihargai ... terutama jika Anda memiliki beberapa nomor untuk menunjukkan bagaimana JWT + kill_table lebih efisien daripada sesi + cache ;-)
tobiasBora

2
@TheTahaan localStorage tidak disarankan untuk menyimpan JWT. Tautan yang Anda bagikan juga menyebutkan hal itu. Blog ini memiliki penjelasan yang baik mengapa JWT tidak boleh disimpan di Penyimpanan lokal.
Harke

40

Jawaban singkatnya adalah: Tidak ada.

Versi yang lebih panjang adalah:

Saya menerapkan JWT untuk manajemen sesi setelah membaca rekomendasi ini di dokumen GraphQL :

Jika Anda tidak terbiasa dengan salah satu mekanisme autentikasi ini, sebaiknya gunakan express-jwt karena sederhana tanpa mengorbankan fleksibilitas di masa mendatang.

Implementasinya memang sederhana karena hanya menambahkan sedikit kerumitan. Namun setelah beberapa saat, saya (menyukai Anda) mulai bertanya-tanya apa manfaatnya. Ternyata ada sangat sedikit (atau mungkin tidak ada) untuk JWT sejauh pengelolaan sesi berjalan, karena posting blog ini menjelaskan secara rinci:

Berhenti menggunakan JWT untuk sesi


0

Dua sen saya, yang dalam perjalanan menambahkan beberapa kontras dengan posting blog terkenal joepie91.

Mempertimbangkan bahwa aplikasi hari ini (dan esok hari) adalah (sebagian besar) cloud native.
Ada manfaat ekonomi dari Autentikasi JWT Tanpa Kewarganegaraan , yang diskalakan seiring dengan skala aplikasi:
Aplikasi cloud menimbulkan biaya seiring dengan setiap tarikan napas .
Biaya ini berkurang ketika pengguna tidak lagi harus mengautentikasi "terhadap" penyimpanan sesi.

Pemrosesan
Menjalankan penyimpanan sesi 24/7 membutuhkan biaya.
Anda tidak bisa lepas dari solusi berbasis memori di dunia K8S, karena pod bersifat sementara.
Sesi yang lengket tidak akan berjalan dengan baik karena alasan yang sama persis.

Penyimpanan
Menyimpan data membutuhkan biaya. menyimpan data dalam SSD lebih mahal.
Operasi terkait sesi harus diselesaikan dengan cepat, jadi drive optik bukanlah pilihan.

I / O
Beberapa penyedia cloud mengenakan biaya untuk I / O terkait Disk.

Bandwidth
Beberapa penyedia cloud mengenakan biaya untuk aktivitas jaringan di antara instance server.
Ini berlaku karena hampir pasti bahwa API dan penyimpanan sesi adalah instance yang terpisah.

Pengelompokan penyimpanan sesi
Biaya meningkatkan semua biaya yang disebutkan di atas lebih jauh.


"Anda tidak dapat lolos dengan solusi berbasis memori di dunia K8S, karena pod bersifat sementara" Tidak yakin apa yang Anda maksud dengan ini. Redis pasti berfungsi di lingkungan K8S, dan pod redis gagal cukup sering untuk memengaruhi pengguna Anda tampaknya sangat tidak mungkin.
quietContest

@quietContest Saya pribadi lebih suka tidak berurusan dengan kemungkinan saat membangun perangkat lunak. BTW, selain stabilitas solusi, serangan dapat menyebabkan perangkat lunak gagal dan pod dimulai ulang - yang akan mengakibatkan hilangnya sesi. Saya akan memilih solusi berbasis JWT karena alasan itu.
Eyal Perry

1
"Saya pribadi memilih untuk tidak berurusan dengan kemungkinan saat membangun perangkat lunak". Saya pikir kita semua lebih suka itu, itulah sebabnya kita tidak boleh merancang sistem yang mengandalkan penyimpanan data dalam memori tidak pernah gagal, karena kemungkinannya tampaknya cukup tinggi. Untuk poin Anda yang lain, jika Anda memiliki penyerang yang dapat secara konsisten mematikan instance redis Anda, solusinya mungkin tidak perlu melibatkan penggunaan JWT.
quietContest

@quietContest secara konsisten atau acara sekali seumur hidup sama bagi saya dalam aspek ini. yaitu serangan DDoS yang ditempatkan dengan baik dapat menyebabkan server "mengeluarkan pengguna". Ini tidak berfungsi dengan baik untuk reputasi keandalan perangkat lunak. Saya pikir redis berlebihan untuk manajemen sesi. Biayanya dan perlu diskalakan, sedangkan (dengan aman) menyimpan JWT dalam cookie tidak.
Eyal Perry

1
@quietContest terima kasih atas masukan Anda, suka pembahasannya!
Eyal Perry

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.