Episode ini membahas pola autentikasi untuk SPA, alur JWT dengan refresh tokens dan penyimpanan yang aman, protecting routes serta role-based access control, dan mitigasi CSRF serta XSS ketika menangani input pengguna di frontend.

Keamanan frontend sering dianggap remeh, padahal di sinilah data pengguna pertama kali disentuh. Episode 12 membahas pola yang benar untuk autentikasi dan otorisasi di aplikasi React: alur login pada SPA, penyimpanan token yang aman, protecting routes, dan role-based access control.
Di paruh kedua kita membahas ancaman nyata yang menghantui setiap frontend — CSRF dan XSS — serta praktik menangani input pengguna dengan aman. Keamanan bukan fitur tambahan; ini persyaratan dasar aplikasi serius.
Pada SPA, autentikasi umumnya berjalan seperti ini: pengguna kirim kredensial, server mengembalikan token, aplikasi menyimpannya lalu memakainya di setiap request berikutnya:
login -> server verifikasi -> token dikirim -> token disimpan -> token dipakai di header AuthorizationToken yang paling umum adalah JWT (JSON Web Token): string berisi header, payload, dan signature yang bisa diverifikasi server tanpa menyimpan sesi. Aplikasi menaruhnya di header Authorization: Bearer <token> pada tiap request.
Satu token yang berlaku lama berisiko besar jika bocor. Pola yang lebih aman memakai dua token:
import axios from "axios"
const api = axios.create({
baseURL: "https://api.example.com",
})
api.interceptors.request.use((config) => {
const token = localStorage.getItem("access_token")
if (token) config.headers.Authorization = `Bearer ${token}`
return config
})Interceptor api.interceptors.request.use((config) => ...) menambahkan header Authorization otomatis ke setiap request. Ketika access token kedaluwarsa, interceptor respons bisa memanggil endpoint refresh untuk memperbaruinya tanpa memaksa pengguna login ulang.
Ini keputusan keamanan penting:
Secure dan SameSite untuk melawan CSRF.Untuk aplikasi produksi, pola yang dianjurkan: access token di memory (state React) dan refresh token di HttpOnly cookie. Jangan pernah menaruh token sensitif di localStorage tanpa pertimbangan risiko XSS.
Gabungkan pattern route guard episode 9 dengan konteks autentikasi:
import { useContext } from "react"
import { Navigate } from "react-router-dom"
import { AuthContext } from "./AuthContext.jsx"
function ProtectedRoute({ anak }) {
const { user } = useContext(AuthContext)
if (!user) return <Navigate to="/login" replace />
return anak
}const { user } = useContext(AuthContext) membaca sesi pengguna. Jika tidak ada, <Navigate to="/login" replace /> mengalihkan ke login. Bungkus route yang sensitif dengan <ProtectedRoute>...</ProtectedRoute>.
Tidak semua pengguna punya hak yang sama. RBAC memeriksa peran pengguna sebelum mengizinkan aksi atau halaman:
function TombolHapus({ user, onClick }) {
if (user.role !== "admin") return null
return <button onClick={onClick}>Hapus</button>
}user.role !== "admin" menyembunyikan tombol dari pengguna non-admin. Ingat aturan emas keamanan: proteksi di frontend hanya untuk UX — otorisasi sebenarnya harus selalu dijalankan di server.
XSS terjadi saat konten tidak tepercaya dirender sebagai HTML. React mem-escape semua teks secara default — menulis {userInput} aman. Bahaya muncul saat kalian memakai dangerouslySetInnerHTML atau memunculkan teks di atribut dengan cara yang salah:
import { DOMPurify } from "dompurify"
function Konten({ html }) {
const bersih = DOMPurify.sanitize(html)
return <div dangerouslySetInnerHTML={{ __html: bersih }} />
}DOMPurify.sanitize(html) membersihkan tag berbahaya sebelum dirender. Gunakan dangerouslySetInnerHTML hanya untuk konten yang sudah disanitasi, dan hindari untuk input langsung pengguna.
CSRF terjadi saat browser tanpa sadar mengirim request ke situs kalian dengan cookie sesi. Mitigasi utama:
SameSite=Lax atau Strict.npm install dompurifyPerintah npm install dompurify memasang library sanitasi HTML. Selalu sanitasi konten yang berasal dari luar sebelum merendernya — ini salah satu kebiasaan keamanan yang paling berdampak.
Episode 12 membekali kalian keamanan frontend: alur autentikasi SPA dengan JWT, pola access dan refresh token, penyimpanan token yang aman, protecting routes dengan RBAC, serta mitigasi CSRF dan XSS.
Inti yang harus dibawa pulang:
Authorization.dangerouslySetInnerHTML.SameSite dan Secure untuk menahan CSRF.Di episode 13 selanjutnya kita akan membahas API integration & error handling — mengonsumsi REST dan GraphQL API, fetch policies dengan retries dan retry delays, centralized error handling dengan fallback UI, serta preloading data dan optimistic updates. Integrasi yang tangguh adalah pembeda aplikasi profesional.