Saya ingin menerapkan otentikasi berbasis JWT ke API REST baru kami. Tetapi karena kedaluwarsa diatur dalam token, apakah mungkin untuk memperpanjangnya secara otomatis? Saya tidak ingin pengguna harus masuk setelah setiap X menit jika mereka aktif menggunakan aplikasi pada periode itu. Itu akan menjadi kegagalan besar UX.
Namun, memperpanjang masa berlaku menciptakan token baru (dan yang lama masih berlaku sampai habis). Dan menghasilkan token baru setelah setiap permintaan terdengar konyol bagi saya. Kedengarannya seperti masalah keamanan ketika lebih dari satu token valid pada saat yang sama. Tentu saja saya bisa membatalkan yang lama menggunakan daftar hitam tapi saya harus menyimpan token. Dan salah satu manfaat JWT adalah tidak ada penyimpanan.
Saya menemukan bagaimana Auth0 menyelesaikannya. Mereka tidak hanya menggunakan token JWT tetapi juga token penyegaran: https://docs.auth0.com/refresh-token
Tetapi sekali lagi, untuk mengimplementasikan ini (tanpa Auth0) saya harus menyimpan token penyegaran dan mempertahankan kedaluwarsa mereka. Apa manfaat sebenarnya? Mengapa tidak hanya memiliki satu token (bukan JWT) dan menyimpan masa berlaku di server?
Apakah ada opsi lain? Apakah menggunakan JWT tidak cocok untuk skenario ini?
Jawaban:
Saya bekerja di Auth0 dan saya terlibat dalam desain fitur token penyegaran.
Itu semua tergantung pada jenis aplikasi dan inilah pendekatan yang kami rekomendasikan.
Aplikasi web
Pola yang baik adalah menyegarkan token sebelum habis.
Atur kedaluwarsa token menjadi satu minggu dan segarkan token setiap kali pengguna membuka aplikasi web dan setiap satu jam. Jika pengguna tidak membuka aplikasi selama lebih dari seminggu, mereka harus masuk lagi dan ini adalah aplikasi web yang dapat diterima.
Untuk menyegarkan token, API Anda memerlukan titik akhir baru yang menerima JWT yang valid, tidak kedaluwarsa, dan mengembalikan JWT bertanda tangan yang sama dengan bidang kedaluwarsa yang baru. Kemudian aplikasi web akan menyimpan token di suatu tempat.
Aplikasi Seluler / Asli
Sebagian besar aplikasi asli melakukan login sekali dan hanya sekali.
Idenya adalah bahwa token penyegaran tidak pernah kedaluwarsa dan dapat ditukar selalu dengan JWT yang valid.
Masalah dengan token yang tidak pernah berakhir adalah itu tidak pernah berarti tidak pernah. Apa yang Anda lakukan jika kehilangan telepon? Jadi, itu harus dapat diidentifikasi oleh pengguna dan aplikasi perlu menyediakan cara untuk mencabut akses. Kami memutuskan untuk menggunakan nama perangkat, misalnya "iPad maryo". Kemudian pengguna dapat pergi ke aplikasi dan mencabut akses ke "maryo iPad".
Pendekatan lain adalah mencabut token penyegaran pada acara tertentu. Acara yang menarik adalah mengubah kata sandi.
Kami percaya bahwa JWT tidak berguna untuk kasus penggunaan ini sehingga kami menggunakan string yang dibuat secara acak dan kami menyimpannya di pihak kami.
sumber
Dalam kasus di mana Anda menangani auth sendiri (yaitu tidak menggunakan penyedia seperti Auth0), berikut ini mungkin berfungsi:
Bendera 'reauth' di backend basis data akan ditetapkan ketika, misalnya, pengguna telah mengatur ulang kata sandi mereka. Bendera akan dihapus ketika pengguna masuk lain kali.
Selain itu, katakanlah Anda memiliki kebijakan di mana pengguna harus masuk setidaknya sekali setiap 72 jam. Jika demikian, logika token penyegaran API Anda juga akan memeriksa tanggal masuk terakhir pengguna dari basis data pengguna dan menolak / memperbolehkan penyegaran token atas dasar itu.
sumber
Saya bermain-main ketika memindahkan aplikasi kami ke HTML5 dengan RESTful apis di backend. Solusi yang saya temukan adalah:
Seperti yang Anda lihat, ini mengurangi permintaan token penyegaran yang sering. Jika pengguna menutup browser / aplikasi sebelum panggilan token dipicu, token sebelumnya akan berakhir dalam waktu dan pengguna harus login ulang.
Strategi yang lebih rumit dapat diterapkan untuk memenuhi ketidakaktifan pengguna (misalnya mengabaikan tab browser yang terbuka). Dalam hal itu, token panggilan perpanjangan harus mencakup waktu berakhir yang diharapkan yang tidak boleh melebihi waktu sesi yang ditentukan. Aplikasi harus melacak interaksi pengguna terakhir yang sesuai.
Saya tidak suka gagasan menetapkan kedaluwarsa yang lama maka pendekatan ini mungkin tidak bekerja dengan baik dengan aplikasi asli yang membutuhkan otentikasi yang lebih jarang.
sumber
Solusi alternatif untuk mematahkan JWT, tanpa penyimpanan aman tambahan di backend, adalah menerapkan
jwt_version
kolom integer baru pada tabel pengguna. Jika pengguna ingin keluar atau kedaluwarsa token yang ada, mereka hanya menambahjwt_version
bidang.Saat membuat JWT baru, encode
jwt_version
ke dalam muatan JWT, secara opsional tambahkan nilainya terlebih dahulu jika JWT baru harus menggantikan yang lainnya.Saat memvalidasi JWT,
jwt_version
bidang tersebut dibandingkan di sampinguser_id
dan otorisasi diberikan hanya jika cocok.sumber
Pertanyaan bagus - dan ada banyak informasi dalam pertanyaan itu sendiri.
Artikel Segarkan Token: Kapan Menggunakan Mereka dan Bagaimana Mereka Berinteraksi dengan JWT memberikan ide bagus untuk skenario ini. Beberapa poin adalah: -
Juga lihat auth0 / angular-jwt angularjs
Untuk API Web. baca Aktifkan OAuth Segarkan Token di Aplikasi AngularJS menggunakan ASP .NET Web API 2, dan Owin
sumber
Saya benar-benar menerapkan ini dalam PHP menggunakan klien Guzzle untuk membuat perpustakaan klien untuk api, tetapi konsep ini harus bekerja untuk platform lain.
Pada dasarnya, saya mengeluarkan dua token, satu pendek (5 menit) satu dan panjang yang berakhir setelah seminggu. Pustaka klien menggunakan middleware untuk mencoba satu penyegaran token pendek jika menerima respons 401 untuk beberapa permintaan. Kemudian akan mencoba permintaan asli lagi dan jika itu bisa me-refresh mendapat respon yang benar, secara transparan kepada pengguna. Jika gagal, itu hanya akan mengirim 401 ke pengguna.
Jika token pendek kedaluwarsa, tetapi masih asli dan token panjang valid dan asli, itu akan menyegarkan token pendek menggunakan titik akhir khusus pada layanan bahwa token panjang mengotentikasi (ini adalah satu-satunya hal yang dapat digunakan untuk). Kemudian akan menggunakan token pendek untuk mendapatkan token panjang baru, sehingga memperpanjangnya seminggu lagi setiap kali menyegarkan token pendek.
Pendekatan ini juga memungkinkan kami untuk mencabut akses dalam waktu paling lama 5 menit, yang dapat diterima untuk penggunaan kami tanpa harus menyimpan daftar hitam token.
Edit terlambat: Membaca ulang bulan ini setelah masih segar di kepala saya, saya harus menunjukkan bahwa Anda dapat mencabut akses ketika menyegarkan token pendek karena memberikan kesempatan untuk panggilan yang lebih mahal (misalnya panggilan ke database untuk melihat apakah pengguna telah dilarang) tanpa membayar untuk setiap panggilan ke layanan Anda.
sumber
Berikut adalah langkah-langkah yang harus dilakukan untuk mencabut token akses JWT Anda:
1) Ketika Anda login, kirim 2 token (Access token, Refresh token) sebagai respons terhadap klien.
2) Token akses akan memiliki waktu kedaluwarsa yang lebih sedikit dan Refresh akan memiliki waktu kedaluwarsa yang lama.
3) Klien (Front end) akan menyimpan token penyegaran di penyimpanan lokalnya dan token akses di cookie.
4) Klien akan menggunakan token akses untuk menelepon apis. Tetapi ketika sudah kedaluwarsa, pilih token penyegaran dari penyimpanan lokal dan panggil auth server api untuk mendapatkan token baru.
5) Server auth Anda akan memiliki api yang terbuka yang akan menerima token penyegaran dan memeriksa validitasnya dan mengembalikan token akses baru.
6) Setelah token penyegaran kadaluarsa, Pengguna akan keluar.
Tolong beri tahu saya jika Anda membutuhkan detail lebih lanjut, saya juga dapat membagikan kode (Java + Spring boot).
sumber
jwt-autorefresh
Jika Anda menggunakan node (React / Redux / Universal JS) Anda dapat menginstal
npm i -S jwt-autorefresh
.Pustaka ini menjadwalkan penyegaran token JWT pada jumlah detik yang dihitung pengguna sebelum token akses kedaluwarsa (berdasarkan klaim exp yang disandikan dalam token). Ini memiliki rangkaian uji ekstensif dan memeriksa beberapa kondisi untuk memastikan aktivitas aneh disertai dengan pesan deskriptif tentang kesalahan konfigurasi dari lingkungan Anda.
Contoh implementasi penuh
disclaimer: Saya adalah pengelola
sumber
jwt-autorefresh
menerjemahkannya adalah mengekstraksiexp
klaim sehingga dapat menentukan seberapa jauh jadwal penjadwalan berikutnya.Saya memecahkan masalah ini dengan menambahkan variabel dalam data token:
Saya mengatur
expiresIn
opsi ke waktu yang saya inginkan sebelum pengguna akan dipaksa untuk masuk lagi. Milik saya diatur ke 30 menit. Ini harus lebih besar dari nilaisoftexp
.Ketika aplikasi sisi klien saya mengirimkan permintaan ke API server (di mana token diperlukan, mis. Halaman daftar pelanggan), server memeriksa apakah token yang dikirimkan masih valid atau tidak berdasarkan nilai kedaluwarsa (
expiresIn
) aslinya . Jika tidak valid, server akan merespons dengan status khusus untuk kesalahan ini, mis.INVALID_TOKEN
.Jika token masih valid berdasarkan
expiredIn
nilai, tetapi sudah melebihisoftexp
nilainya, server akan merespons dengan status terpisah untuk kesalahan ini, mis.EXPIRED_TOKEN
:Di sisi klien, jika menerima
EXPIRED_TOKEN
respons, token harus diperbarui secara otomatis dengan mengirim permintaan pembaruan ke server. Ini transparan bagi pengguna dan secara otomatis dirawat oleh aplikasi klien.Metode pembaruan di server harus memeriksa apakah token masih valid:
Server akan menolak untuk memperbarui token jika gagal metode di atas.
sumber
Bagaimana dengan pendekatan ini:
Kami tidak memerlukan titik akhir tambahan untuk menyegarkan token dalam kasus ini. Akan menghargai umpan balik.
sumber
Saat ini, banyak orang memilih untuk melakukan manajemen sesi dengan JWT tanpa menyadari apa yang mereka berikan demi kesederhanaan yang dirasakan . Jawaban saya menguraikan bagian ke-2 dari pertanyaan:
JWT mampu mendukung manajemen sesi dasar dengan beberapa keterbatasan. Menjadi token yang menggambarkan sendiri, mereka tidak memerlukan keadaan apa pun di sisi server. Ini membuat mereka menarik. Misalnya, jika layanan tidak memiliki lapisan ketekunan, ia tidak perlu memasukkannya hanya untuk manajemen sesi.
Namun, kewarganegaraan juga merupakan penyebab utama dari kekurangan mereka. Karena mereka hanya dikeluarkan satu kali dengan konten tetap dan kedaluwarsa, Anda tidak dapat melakukan hal-hal yang ingin Anda lakukan dengan pengaturan manajemen sesi yang khas.
Yaitu, Anda tidak dapat membatalkannya berdasarkan permintaan. Ini berarti Anda tidak dapat menerapkan logout aman karena tidak ada cara untuk kedaluwarsa token yang sudah dikeluarkan. Anda juga tidak dapat menerapkan batas waktu idle karena alasan yang sama. Salah satu solusinya adalah menyimpan daftar hitam, tetapi hal itu memperkenalkan keadaan.
Saya menulis posting yang menjelaskan kekurangan ini secara lebih rinci. Agar lebih jelas, Anda dapat menyiasatinya dengan menambahkan lebih banyak kompleksitas (sesi geser, menyegarkan token, dll.)
Adapun opsi lain, jika klien Anda hanya berinteraksi dengan layanan Anda melalui browser, saya sangat menyarankan menggunakan solusi manajemen sesi berbasis cookie. Saya juga menyusun metode otentikasi daftar yang saat ini banyak digunakan di web.
sumber