Pantau Semua HP & Komputer yang Sedang Masuk
Melihat lokasi dan tipe perangkat yang sedang login, serta tombol darurat untuk memutuskan koneksi perangkat lain dari jarak jauh jika laptop tertinggal di kantor.
Melihat lokasi dan tipe perangkat yang sedang login, serta tombol darurat untuk memutuskan koneksi perangkat lain dari jarak jauh jika laptop tertinggal di kantor.
Tantangan & Kebutuhan Pengguna
Stateless JWT tradisional memiliki kelemahan fatal: begitu token diterbitkan, server tidak dapat mencabutnya sampai masa kedaluwarsanya habis. Jika laptop pengguna hilang atau akun disusupi, mengganti password tidak akan menghentikan sesi penyerang yang masih memegang token aktif. Sebaliknya, melakukan update database pada setiap request membuat beban tulis (write amplification) database melonjak tajam.
Keamanan sesi sejati membutuhkan kemampuan mencabut akses perangkat mana pun dalam hitungan milidetik tanpa mengorbankan performa pada setiap request halaman.
Solusi & Cara Kerja
Setiap kali login berhasil, sistem membuat baris di tabel `user_sessions` yang mencatat alamat IP, User-Agent, dan waktu kedaluwarsa, lalu menyematkan UUID baris tersebut ke dalam klaim `sid` beserta `ver` (`sessionVersion`) pada token JWT HS256. Ketika `getSession()` dipanggil, sistem memverifikasi tanda tangan kriptografis token, mencocokkan keberadaan baris `sid` di database, memastikan akun masih `isActive`, dan membandingkan `payload.ver === user.sessionVersion`. Saat terjadi perubahan sensitif (ganti email, ubah role, aktivasi/nonaktif MFA), `sessionVersion` dinaikkan (`increment: 1`) sehingga seluruh token lama di perangkat lain otomatis gugur seketika.
Berikut adalah implementasi resolusi sesi ter-cache dengan throttling pembaruan `lastSeenAt` di `common/lib/auth.ts`:
Detail & Hal yang Diperhatikan
- Write-Amplification Throttling: Kolom `lastSeenAt` tidak diperbarui pada setiap pembacaan halaman, melainkan di-throttle maksimal satu kali setiap 5 menit per perangkat.
- Pembersihan Otomatis Sesi Kedaluwarsa: Setiap kali pengguna melakukan login baru (`createSession`), baris sesi milik pengguna tersebut yang sudah melewati `expiresAt` langsung dibersihkan dari database.
- Proteksi Self-Revocation: Fungsi `revokeSession` memvalidasi `sessionUuid !== currentSessionUuid` agar pengguna tidak mencabut sesi yang sedang dipakainya secara tidak sengaja dari daftar perangkat.
Pemanggilan `await connection()` dari `next/server` sebelum membaca `cookies()` memastikan kompatibilitas penuh dengan model rendering dinamis Next.js 16 App Router.