Lewati ke konten utama

Autentikasi dan Sesi

Pendahuluan

Dokumen ini menjelaskan alur autentikasi frontend, penyimpanan sesi cookie, perlindungan rute, penanganan izin, dan perilaku logout.


Alur Login

Halaman login adalah src/pages/LoginPage.tsx.

Alur tingkat tinggi:

  1. Kredensial: Pengguna mengirimkan email dan kata sandi.
  2. Panggilan API: Halaman memanggil api.auth.login(credentials).
  3. Ekstraksi Data: Jika berhasil, halaman mengekstrak token, user.id, dan user.organizationId.
  4. Penyimpanan Sesi: Halaman memanggil auth.setAuth(...).
  5. Navigasi: Halaman menunjukkan umpan balik sukses dan menavigasi ke /dashboard.

Respons login yang diharapkan bertipe:

interface AuthResponse {
token: string;
user: User;
}

Frontend mengharapkan backend mengembalikan respons ini di dalam pembungkus API standar:

interface ApiResponse<T> {
success: boolean;
data: T;
errors: string[];
traceId?: string | null;
}

Penyimpanan sesi dikelola oleh src/lib/auth.ts dengan js-cookie.

Kunci CookieKonstanta SumberTujuan
access_tokenCOOKIE_KEYS.ACCESS_TOKENToken bearer untuk panggilan API
user_idCOOKIE_KEYS.USER_IDID pengguna saat ini
organization_idCOOKIE_KEYS.ORGANIZATION_IDCakupan organisasi saat ini
user_nameCOOKIE_KEYS.USER_NAMEKonstanta cadangan, tidak digunakan di alur utama
user_emailCOOKIE_KEYS.USER_EMAILKonstanta cadangan, tidak digunakan di alur utama

Opsi cookie:

OpsiNilai
securetrue ketika protokol halaman saat ini HTTPS
sameSitestrict
expires7 hari

Perlindungan Rute (Route Protection)

PrivateRoutes di src/app/PrivateRoutes.tsx melindungi semua rute /dashboard.

Guard menggunakan pemeriksaan ini saja:

auth.isAuthenticated()

isAuthenticated() mengembalikan nilai true ketika access_token ada di cookie. Validitas token ditegakkan oleh backend pada panggilan API, bukan dengan mendekode token di sisi klien.


Autentikasi API

src/lib/api.ts membuat instans Axios terpusat. Interceptor permintaan membaca auth.getToken() dan melampirkan:

Authorization: Bearer <token>

Interceptor respons menangani HTTP 401:

  1. Bersihkan cookie auth.
  2. Alihkan browser ke /.
  3. Tolak promise permintaan asli.

Klien streaming chat analitik di src/lib/analyticsChat.ts menggunakan fetch daripada Axios, tetapi mengikuti aturan token yang sama dan membersihkan sesi pada 401.


Pengguna Saat Ini dan Izin

src/hooks/useApi.ts mengekspos useUserPermissions().

Hook tersebut:

  1. Memeriksa auth.isAuthenticated().
  2. Memanggil api.auth.me().
  3. Membaca izin dari user.role.permissions.
  4. Mengekspos hasPermission(slug).

Slug izin dipusatkan di src/lib/constants.ts:

DomainSlug
Sensorscreate-sensor, update-sensor, delete-sensor, read-sensor
Userscreate-user, edit-user, delete-user, read-user
Rolescreate-role, edit-role, delete-role, read-role
Organizationedit-organization

Layar fitur menggunakan slug ini untuk menampilkan atau menyembunyikan tindakan buat, edit, dan hapus. Backend tetap bertanggung jawab atas penegakan otorisasi akhir.


Alur Logout

Logout dipicu dari menu pengguna shell dasbor.

Alur:

  1. Konfirmasi: Tampilkan dialog konfirmasi melalui showConfirm.
  2. Panggilan API: Panggil api.auth.logout().
  3. Pembersihan Sesi: Bersihkan cookie auth dengan auth.clearAuth().
  4. Umpan Balik: Tampilkan pesan sukses.
  5. Navigasi: Navigasi ke /.

Jika panggilan logout backend gagal, frontend tetap membersihkan data auth lokal dan menavigasi ke /.


Mode Kegagalan Sesi

SkenarioPerilaku Frontend
Token hilang sebelum masuk dasborAlihkan ke /
API mengembalikan 401Bersihkan cookie dan alihkan ke /
/auth/me gagal di hook izinDaftar izin menjadi kosong
API logout gagalAuth lokal tetap dibersihkan
Cookie ID pengguna hilang di shellShell melewati pengambilan data pengguna saat ini

Catatan Keamanan

  • Frontend menyimpan token bearer di cookie, bukan di localStorage.
  • Cookie bersifat sameSite: strict, mengurangi risiko permintaan lintas situs (CSRF).
  • Bendera secure bergantung pada penyajian aplikasi melalui HTTPS.
  • Frontend tidak mengimplementasikan penyegaran token (token refresh).
  • Frontend tidak mendekode klaim JWT; ia bergantung pada titik akhir backend untuk pengguna saat ini dan izin.