Episode ini membahas autentikasi di Remix: session handling dengan cookies, pola login berbasis form dan action, proteksi route dengan guard di loader, serta OAuth dan social login memakai remix-auth.

Setiap aplikasi yang menyimpan data pengguna suatu saat butuh menjawab satu pertanyaan: siapa yang sedang memakai aplikasi ini? Jawabannya disebut autentikasi, dan cara Remix menanganinya sama konsistennya dengan hal lain: lewat request dan response HTTP.
Model autentikasi di Remix sederhana namun kuat. Setelah login berhasil, action menyimpan identitas pengguna ke dalam session yang disimpan di cookie. Setiap request berikutnya, loader membaca cookie tersebut untuk mengenali pengguna. Tidak ada state global di memory — semuanya berjalan lewat mekanisme web standar.
Episode 11 akan membangun autentikasi dari nol: session cookies, form login, proteksi route, lalu integrasi OAuth dan social login dengan remix-auth.
Session storage dibangun dengan createCookieSessionStorage dari @remix-run/node. Ia menyimpan data session di cookie yang di-enkripsi — isinya tidak bisa dibaca pengguna.
import { createCookieSessionStorage } from "@remix-run/node";
export const sessionStorage = createCookieSessionStorage({
cookie: {
name: "__session",
httpOnly: true,
sameSite: "lax",
secrets: [process.env.SESSION_SECRET],
secure: process.env.NODE_ENV === "production",
},
});Secrets pada cookie digunakan untuk menandatangani isi session. httpOnly mencegah akses dari JavaScript, dan secure memastikan cookie hanya lewat HTTPS di production.
Session dibaca dengan getSession dan dimodifikasi lewat method set dan get. Perubahan baru berlaku setelah commitSession mengembalikan cookie yang di-set di header respons.
Model paling dasar: form login dikirim ke action, action memverifikasi kredensial, lalu menyimpan user id ke session:
import { redirect } from "@remix-run/node";
import { sessionStorage } from "~/lib/session.server";
export async function action({ request }) {
const formData = await request.formData();
const email = String(formData.get("email"));
const password = String(formData.get("password"));
const user = await verifikasiKredensial(email, password);
if (!user) return { error: "Email atau password salah" };
const session = await sessionStorage.getSession(
request.headers.get("Cookie"),
);
session.set("userId", user.id);
return redirect("/dasbor", {
headers: {
"Set-Cookie": await sessionStorage.commitSession(session),
},
});
}commitSession menghasilkan header Set-Cookie yang disimpan browser. Setelah ini, setiap request membawa cookie session dan identitas pengguna bisa dibaca.
Jangan pernah menyimpan password polos. Gunakan fungsi hash yang dirancang untuk password, seperti bcrypt atau argon2. Verifikasi memakai perbandingan hash, bukan perbandingan string biasa. Library seperti bcryptjs mudah diintegrasikan di loader dan action.
Proteksi route dilakukan di loader: baca session, jika tidak ada user, redirect ke halaman login. Karena loader berjalan di server, halaman terproteksi tidak pernah ter-render tanpa izin.
export async function loader({ request }) {
const session = await sessionStorage.getSession(
request.headers.get("Cookie"),
);
const userId = session.get("userId");
if (!userId) return redirect("/login");
return { userId };
}Guard ini menjadi kebiasaan: setiap route privat memulai loader dengan cek session. Untuk menghindari pengulangan, buat helper requireUser(request) di modul bersama — pola ini akan dirapikan di episode 18.
Karena session hanya berisi id, loader biasanya mengambil data pengguna dari database lalu mengembalikannya ke komponen. Untuk user yang dipakai di banyak route, pertimbangkan memuatnya di root layout dan membagikannya lewat context React atau hook.
Membangun OAuth dari nol rawan kesalahan. Library remix-auth menyediakan strategi untuk Google, GitHub, dan banyak provider lain. Konsepnya: aplikasi mengarahkan pengguna ke provider, provider mengirim kembali kode, dan strategi menukar kode tersebut dengan profil user.
npm install remix-auth remix-auth-googleInstal strategi provider sesuai kebutuhan; konsepnya seragam untuk semua. Flow-nya tetap mengikuti pola Remix: action login menangani callback, dan session dibangun setelah profil didapat.
Beberapa hal yang wajib diperhatikan:
Episode 11 menyelesaikan autentikasi ujung ke ujung: session cookies yang aman, login berbasis form dengan guard di loader, serta OAuth dan social login via remix-auth. Aplikasi kalian sekarang bisa mengenali penggunanya.
Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membahas security best practices — secure headers dan content security policy, pencegahan XSS, CSRF, dan injection, validasi input serta sanitasi di server, dan penanganan secret yang aman. Autentikasi membuka pintu; keamanan menjaga seluruh rumahnya.