JWT (JSON Web Token) perpanjangan otomatis dari kedaluwarsa


509

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?


1
Sebenarnya mungkin tidak ada masalah keamanan dengan banyak token yang valid sekaligus ... Sebenarnya ada jumlah token yang valid tak terbatas ... Jadi, mengapa memiliki token penyegaran? Saya akan membuat ulang mereka setelah setiap permintaan, itu seharusnya tidak menjadi masalah.
maryo

1
Untuk SPA, periksa
wong2

2
@maryo Saya pikir memiliki (berpotensi) ratusan atau ribuan JWT valid yang tidak digunakan di luar sana pada waktu tertentu meningkatkan jejak serangan Anda dan merupakan risiko keamanan. Dalam pikiranku, JWT harus dikeluarkan dengan hati-hati karena mereka mengakses token dengan kunci kastil dengan cara.
java-addict301

Jawaban:


590

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.


42
Untuk pendekatan aplikasi web yang direkomendasikan, jika token itu valid selama seminggu, apakah kita tidak peduli dengan seseorang yang mencegat token dan kemudian dapat menggunakannya untuk waktu yang lama? Penafian: Saya tidak tahu apa yang saya bicarakan.
user12121234

30
@wange ya intersepsi adalah masalah, bahkan dengan cookie. Anda harus menggunakan https.
José F. Romaniello

15
@ JoséF.Romaniello Dalam contoh aplikasi web Anda, semuanya masuk akal bagi saya kecuali harus menyimpan token. Saya pikir keindahan JWT adalah otentikasi tanpa kewarganegaraan - artinya aplikasi web TIDAK harus menyimpan token saat ditandatangani. Saya akan berpikir server hanya dapat memeriksa validitas token, pastikan itu dalam periode kedaluwarsa, dan kemudian mengeluarkan token JWT yang diperbarui. Bisakah Anda jelaskan ini? Mungkin saya belum cukup memahami JWT.
Lo-Tan

7
Dua pertanyaan / masalah: 1- Kasus Aplikasi Web: mengapa token yang kedaluwarsa tidak diizinkan mendapatkan penyegaran? Katakanlah kita menetapkan kadaluarsa singkat (1 jam) & melakukan panggilan baru ke server backend ketika token berakhir, seperti yang Anda katakan. 2- Apakah ada masalah keamanan dengan menyimpan kata sandi hash (dengan garam acak) di token? Idenya adalah bahwa jika ada di sana, server backend dapat memeriksa terhadap kata sandi yang disimpan dalam DB ketika diminta untuk pembaruan, & menolak permintaan jika kata sandi tidak cocok. Ini akan mencakup perubahan kata sandi aplikasi Seluler / Asli, yang memungkinkan solusi diperluas ke Kasing Seluler.
psamaan

8
-1 Mengekspos API publik yang secara buta menandatangani ulang token apa pun untuk memperpanjang periode validasinya buruk. Sekarang semua token Anda memiliki masa berlaku tak terbatas yang efektif. Tindakan menandatangani token harus mencakup pemeriksaan auth yang sesuai untuk masing-masing dan setiap klaim yang dibuat dalam token tersebut pada saat penandatanganan.
Phil

69

Dalam kasus di mana Anda menangani auth sendiri (yaitu tidak menggunakan penyedia seperti Auth0), berikut ini mungkin berfungsi:

  1. Menerbitkan token JWT dengan masa berlaku yang relatif singkat, misalnya 15 menit.
  2. Aplikasi memeriksa tanggal kedaluwarsa token sebelum transaksi yang memerlukan token (token berisi tanggal kedaluwarsa). Jika token telah kedaluwarsa, maka pertama-tama ia meminta API untuk 'menyegarkan' token (ini dilakukan secara transparan ke UX).
  3. API mendapat permintaan penyegaran token, tetapi pertama-tama memeriksa basis data pengguna untuk melihat apakah bendera 'reauth' telah ditetapkan terhadap profil pengguna tersebut (token dapat berisi id pengguna). Jika flag ada, maka token refresh ditolak, jika tidak token baru dikeluarkan.
  4. Ulang.

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.


7
Saya tidak berpikir ini akan aman. Jika saya seorang penyerang dan mencuri token Anda dan mengirimkannya ke server, server akan memeriksa dan melihat bendera disetel ke true yang sangat bagus karena akan memblokir penyegaran. Masalahnya saya pikir akan jika korban mengubah kata sandi mereka bendera akan disetel ke false dan sekarang penyerang dapat menggunakan token asli untuk menyegarkan.
user2924127

6
@ user2924127 tidak ada solusi auth sempurna, dan akan selalu ada pengorbanan. Jika penyerang berada dalam posisi untuk 'mencuri token Anda', maka Anda mungkin memiliki masalah yang lebih besar untuk dikhawatirkan. Menyetel token seumur hidup maksimum akan menjadi perubahan yang bermanfaat untuk hal di atas.
IanB

27
alih-alih memiliki bidang lain dalam database, tandai kembali, Anda dapat memasukkan untuk hash (bcrypt_password_hash) di token. Kemudian ketika menyegarkan token, Anda cukup mengonfirmasi apakah hash (bcrypt_password_hash) sama dengan nilai dari token. Untuk menolak token refresh, kita hanya perlu memperbarui hash kata sandi.
bas

4
@Bas, berpikir dalam optimasi dan kinerja, saya pikir validasi kata sandi akan berlebihan dan memiliki lebih banyak implikasi server. Tingkatkan ukuran token sehingga perusahaan tanda tangan / validasi membutuhkan waktu lebih lama. perhitungan hash tambahan untuk server untuk kata sandi. dengan pendekatan bidang tambahan Anda baru saja memvalidasi dalam perhitungan ulang dengan boolean sederhana. Pembaruan Db lebih jarang untuk bidang tambahan, tetapi lebih sering menyegarkan token. Dan Anda mendapatkan layanan opsional login ulang paksa individu untuk setiap sesi yang ada (seluler, web, dll).
le0diaz

6
Saya pikir komentar pertama oleh user2924127 sebenarnya salah. Ketika kata sandi diubah, akun ditandai sebagai memerlukan otentikasi ulang, sehingga token yang sudah kadaluwarsa akan menjadi tidak valid.
Ralph

15

Saya bermain-main ketika memindahkan aplikasi kami ke HTML5 dengan RESTful apis di backend. Solusi yang saya temukan adalah:

  1. Klien diberikan dengan token dengan waktu sesi 30 menit (atau apa pun waktu sesi sisi server yang biasa) setelah login berhasil.
  2. Timer sisi klien dibuat untuk memanggil layanan untuk memperbarui token sebelum waktu kedaluwarsa. Token baru akan menggantikan yang ada di panggilan berikutnya.

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.


1
Bagaimana jika komputer ditangguhkan / tidur. Timer masih akan dihitung sampai kedaluwarsa tetapi token sebenarnya sudah kadaluwarsa. Timer tidak berfungsi dalam situasi ini
Alex Parij

@AlexParij Anda akan membandingkan dengan waktu yang tetap, sesuatu seperti ini: stackoverflow.com/a/35182296/1038456
Aparajita

2
Mengizinkan klien untuk meminta token baru dengan tanggal kedaluwarsa yang disukai bau seperti risiko keamanan bagi saya.
java-addict301

14

Solusi alternatif untuk mematahkan JWT, tanpa penyimpanan aman tambahan di backend, adalah menerapkan jwt_versionkolom integer baru pada tabel pengguna. Jika pengguna ingin keluar atau kedaluwarsa token yang ada, mereka hanya menambah jwt_versionbidang.

Saat membuat JWT baru, encode jwt_versionke dalam muatan JWT, secara opsional tambahkan nilainya terlebih dahulu jika JWT baru harus menggantikan yang lainnya.

Saat memvalidasi JWT, jwt_versionbidang tersebut dibandingkan di samping user_iddan otorisasi diberikan hanya jika cocok.


1
Ini memiliki masalah dengan beberapa perangkat. Intinya jika Anda logout pada satu perangkat, itu logout di mana-mana. Baik?
Sam Washburn

4
Hei, itu mungkin bukan "masalah" tergantung pada kebutuhan Anda, tetapi Anda benar; ini tidak mendukung manajemen sesi per perangkat.
Ollie Bennett

Bukankah ini berarti jwt_version harus disimpan di sisi server sehingga skema otentikasi menjadi "seperti sesi" dan mengalahkan tujuan mendasar JWT?
ChetPrickles

8

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: -

  • Segarkan token membawa informasi yang diperlukan untuk mendapatkan token akses baru.
  • Segarkan token juga dapat kedaluwarsa tetapi berumur panjang.
  • Segarkan token biasanya tunduk pada persyaratan penyimpanan yang ketat untuk memastikan mereka tidak bocor.
  • Mereka juga dapat masuk daftar hitam oleh server otorisasi.

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


Mungkin saya salah membacanya ... Tapi artikel dengan judul yang dimulai dengan "Refresh Token ..." tidak memuat apa pun tentang token penyegaran, kecuali apa yang Anda sebutkan di sini.
Ievgen Martynov

8

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.


8

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).


Bisakah Anda membagikan tautan proyek Anda jika Anda memilikinya di GitHub?
Arun Kumar N


6

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

import autorefresh from 'jwt-autorefresh'

/** Events in your app that are triggered when your user becomes authorized or deauthorized. */
import { onAuthorize, onDeauthorize } from './events'

/** Your refresh token mechanism, returning a promise that resolves to the new access tokenFunction (library does not care about your method of persisting tokens) */
const refresh = () => {
  const init =  { method: 'POST'
                , headers: { 'Content-Type': `application/x-www-form-urlencoded` }
                , body: `refresh_token=${localStorage.refresh_token}&grant_type=refresh_token`
                }
  return fetch('/oauth/token', init)
    .then(res => res.json())
    .then(({ token_type, access_token, expires_in, refresh_token }) => {
      localStorage.access_token = access_token
      localStorage.refresh_token = refresh_token
      return access_token
    })
}

/** You supply a leadSeconds number or function that generates a number of seconds that the refresh should occur prior to the access token expiring */
const leadSeconds = () => {
  /** Generate random additional seconds (up to 30 in this case) to append to the lead time to ensure multiple clients dont schedule simultaneous refresh */
  const jitter = Math.floor(Math.random() * 30)

  /** Schedule autorefresh to occur 60 to 90 seconds prior to token expiration */
  return 60 + jitter
}

let start = autorefresh({ refresh, leadSeconds })
let cancel = () => {}
onAuthorize(access_token => {
  cancel()
  cancel = start(access_token)
})

onDeauthorize(() => cancel())

disclaimer: Saya adalah pengelola


Pertanyaan tentang ini, saya melihat fungsi decode yang digunakannya. Apakah ia menganggap JWT dapat diterjemahkan tanpa menggunakan rahasia? Apakah ini berfungsi dengan JWT yang ditandatangani dengan rahasia?
Gian Franco Zabarino

3
Ya, decode adalah decode khusus klien dan tidak boleh mengetahui rahasia. Rahasianya digunakan untuk menandatangani sisi server token JWT untuk memverifikasi bahwa tanda tangan Anda awalnya digunakan untuk menghasilkan JWT dan tidak boleh digunakan dari klien. Keajaiban JWT adalah bahwa muatannya dapat didekodekan dari sisi klien dan klaim di dalamnya dapat digunakan untuk membangun UI Anda tanpa rahasia. Satu-satunya yang jwt-autorefreshmenerjemahkannya adalah mengekstraksi expklaim sehingga dapat menentukan seberapa jauh jadwal penjadwalan berikutnya.
cchamberlain

1
Oh, bagus untuk tahu, ada sesuatu yang tidak masuk akal tapi sekarang sudah. Terima kasih atas jawabannya.
Gian Franco Zabarino

4

Saya memecahkan masalah ini dengan menambahkan variabel dalam data token:

softexp - I set this to 5 mins (300 seconds)

Saya mengatur expiresInopsi ke waktu yang saya inginkan sebelum pengguna akan dipaksa untuk masuk lagi. Milik saya diatur ke 30 menit. Ini harus lebih besar dari nilai softexp.

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 expiredInnilai, tetapi sudah melebihi softexpnilainya, server akan merespons dengan status terpisah untuk kesalahan ini, mis. EXPIRED_TOKEN:

(Math.floor(Date.now() / 1000) > decoded.softexp)

Di sisi klien, jika menerima EXPIRED_TOKENrespons, 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:

jwt.verify(token, secret, (err, decoded) => {})

Server akan menolak untuk memperbarui token jika gagal metode di atas.


Strategi ini terlihat bagus. Tapi saya pikir harus dilengkapi dengan semacam "jumlah maksimum pembaruan" karena (mungkin) session pengguna dapat hidup selamanya.
Juan Ignacio Barisich

1
Anda dapat mengatur variabel hardExp dalam data token untuk menetapkan tanggal max untuk memaksa expire token, atau mungkin penghitung yang dikurangi setiap kali token diperbarui, membatasi jumlah total token yang diperbarui.
James A

1
itu benar. Saya menganggap ini sebagai "keharusan".
Juan Ignacio Barisich

2

Bagaimana dengan pendekatan ini:

  • Untuk setiap permintaan klien, server membandingkan expirationTime dari token dengan (currentTime - lastAccessTime)
  • Jika expirationTime <(currentTime - lastAccessedTime) , itu mengubah LastAccessedTime terakhir ke currentTime.
  • Dalam hal tidak aktif pada browser untuk durasi waktu melebihi expirationTime atau jika jendela browser ditutup dan expirationTime> (currentTime - lastAccessedTime) , dan kemudian server dapat kedaluwarsa token dan meminta pengguna untuk login lagi.

Kami tidak memerlukan titik akhir tambahan untuk menyegarkan token dalam kasus ini. Akan menghargai umpan balik.


Apakah ini pilihan yang baik di hari ini, Ini terlihat cukup mudah untuk implementasi.
b.ben

4
Dalam hal ini, di mana Anda menyimpan lastAccessedTime? Anda harus melakukannya di backend dan per permintaan, sehingga menjadi solusi stateful yang tidak diinginkan.
antgar9

2

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:

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?

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.

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.