# Lucia Auth: Otentikasi Modern untuk TypeScript, Bun, dan Hono

Otentikasi (authentication) adalah jantung keamanan sebuah aplikasi.  
Namun, membuat sistem login dari nol sering kali merepotkan:

* Harus mengelola hash password (bcrypt, argon2)
    
* Membuat sesi aman (cookies, JWT, CSRF)
    
* Mengatur login dengan provider OAuth (Google, GitHub, dst)
    
* Menulis middleware untuk memeriksa user login
    
* Menjamin semua berjalan aman di berbagai platform (Node.js, Edge, Bun)
    

Nah, **Lucia Auth** hadir untuk menjawab semua itu dengan prinsip:

> “A simple and type-safe authentication library for the modern web.”

---

## ⚙️ Apa Itu Lucia?

**Lucia** adalah library otentikasi open-source berbasis TypeScript yang:

* Ringan dan modular (tidak seperti NextAuth yang besar dan opiniated)
    
* Mendukung berbagai runtime: **Node.js, Bun, Deno, Cloudflare Workers**
    
* Tidak bergantung framework (bisa dipakai di **Hono, Elysia, Next.js, SvelteKit**, dll)
    
* Memiliki integrasi database yang luas (Prisma, Drizzle, LibSQL, PlanetScale, dsb)
    
* Fokus pada **type safety**, **clean code**, dan **keamanan modern**
    

Lucia bertujuan agar kamu bisa membuat login, register, dan session management dengan **kontrol penuh**, tapi **tanpa boilerplate**.

---

## 🧩 Arsitektur Dasar Lucia

Secara garis besar, Lucia bekerja dengan tiga komponen utama:

1. **User** — data pengguna yang disimpan di database.
    
2. **Session** — identitas sementara pengguna yang sedang login.
    
3. **Adapter** — jembatan antara Lucia dan database (Prisma, Drizzle, dsb).
    

```typescript
Client  ⇄  Server (Lucia) ⇄  Database (Drizzle/Prisma)
```

---

## 🚀 Instalasi

Contoh setup dengan **Node.js / Bun** dan **Drizzle ORM**:

```bash
npm install lucia @lucia-auth/adapter-drizzle drizzle-orm
```

---

## 🧱 Setup Dasar Lucia

Buat file `auth.ts`:

```ts
import { Lucia } from "lucia";
import { DrizzleAdapter } from "@lucia-auth/adapter-drizzle";
import { db } from "./db";
import { sessionTable, userTable } from "./schema";

export const lucia = new Lucia(new DrizzleAdapter(db, sessionTable, userTable), {
  sessionCookie: {
    name: "session",
    attributes: {
      secure: process.env.NODE_ENV === "production"
    }
  },
  getUserAttributes: (data) => ({
    username: data.username
  })
});

export type Auth = typeof lucia;
```

Penjelasan:

* `DrizzleAdapter` menyambungkan Lucia ke database
    
* `sessionCookie` mengatur nama cookie dan keamanannya
    
* `getUserAttributes` menentukan data yang akan diakses di `user`
    

---

## 🧰 Skema Database

Contoh skema Drizzle:

```ts
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";

export const userTable = pgTable("user", {
  id: text("id").primaryKey(),
  username: text("username").notNull(),
  hashed_password: text("hashed_password").notNull(),
});

export const sessionTable = pgTable("session", {
  id: text("id").primaryKey(),
  user_id: text("user_id")
    .notNull()
    .references(() => userTable.id),
  expires_at: timestamp("expires_at", { withTimezone: true }).notNull(),
});
```

---

## 🔑 Register (Sign Up)

```ts
import { lucia } from "./auth";
import { generateId } from "lucia";
import { Argon2id } from "oslo/password";

const passwordHasher = new Argon2id();

export async function register(username: string, password: string) {
  const userId = generateId(15);
  const hashedPassword = await passwordHasher.hash(password);

  await db.insert(userTable).values({
    id: userId,
    username,
    hashed_password: hashedPassword
  });

  const session = await lucia.createSession(userId, {});
  const sessionCookie = lucia.createSessionCookie(session.id);

  return { sessionCookie };
}
```

Lucia memakai library **Oslo** (resmi dari Lucia) untuk hashing password dengan standar tinggi seperti Argon2id — aman dan cepat.

---

## 🔐 Login (Sign In)

```ts
export async function login(username: string, password: string) {
  const existingUser = await db.query.userTable.findFirst({
    where: (u, { eq }) => eq(u.username, username)
  });

  if (!existingUser) throw new Error("User not found");

  const valid = await passwordHasher.verify(
    existingUser.hashed_password,
    password
  );

  if (!valid) throw new Error("Invalid password");

  const session = await lucia.createSession(existingUser.id, {});
  const sessionCookie = lucia.createSessionCookie(session.id);

  return { sessionCookie };
}
```

---

## 🧾 Middleware: Memeriksa User yang Login

Lucia menyediakan cara mudah untuk memvalidasi session dari request:

```ts
import { lucia } from "./auth";

export async function getUserFromRequest(request: Request) {
  const session = await lucia.validateRequest(request);
  if (!session) return null;
  return session.user;
}
```

Kamu bisa gunakan fungsi ini di middleware Hono atau Next.js API Route untuk melindungi route privat.

---

## 🧠 Integrasi dengan Hono

Contoh route login sederhana:

```ts
import { Hono } from "hono";
import { login, register } from "./auth-controller";
import { lucia } from "./auth";

const app = new Hono();

app.post("/login", async (c) => {
  const { username, password } = await c.req.json();
  const { sessionCookie } = await login(username, password);
  c.header("Set-Cookie", sessionCookie.serialize());
  return c.json({ success: true });
});

app.get("/me", async (c) => {
  const auth = await lucia.validateRequest(c.req);
  if (!auth) return c.json({ user: null });
  return c.json({ user: auth.user });
});
```

---

## 🌍 Login dengan Google atau GitHub (OAuth)

Lucia menyediakan package resmi untuk OAuth:

```bash
npm install @lucia-auth/oauth
```

Contoh integrasi Google:

```ts
import { google } from "@lucia-auth/oauth/providers";
import { lucia } from "./auth";

export const googleAuth = google(lucia, {
  clientId: process.env.GOOGLE_CLIENT_ID!,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
  redirectUri: "https://example.com/api/callback/google"
});
```

Saat user login lewat Google:

1. Arahkan ke `googleAuth.getAuthorizationUrl()`
    
2. Setelah redirect, tangkap `code` dan panggil `googleAuth.validateCallback(code)`
    
3. Lucia akan otomatis membuat atau menemukan user di database
    

---

## 🔒 Keamanan Lucia

Lucia dibangun dengan prinsip keamanan tinggi:

* Menggunakan **cookie-based session**, bukan JWT (lebih aman untuk web)
    
* Tidak menyimpan token rahasia di localStorage
    
* Sesi otomatis **kadaluarsa** dan dapat diperbarui
    
* Password hashing menggunakan **Argon2id (via Oslo)**
    
* Type-safe di seluruh proses
    

---

## ⚡ Dibandingkan Library Lain

| Fitur | **Lucia** | **NextAuth.js** | **Passport.js** |
| --- | --- | --- | --- |
| Framework agnostic | ✅ Ya | ❌ Khusus Next.js | ⚠️ Untuk Express |
| Type safety | ✅ Kuat (Zod + TS) | ⚠️ Terbatas | ❌ Tidak ada |
| OAuth (Google, GitHub, dst) | ✅ Mudah | ✅ Banyak provider | ✅ Banyak provider |
| Session cookie | ✅ Built-in | ✅ | ⚠️ Bergantung plugin |
| Database bebas | ✅ (Drizzle, Prisma, SQL, dll) | ⚠️ Perlu adapter khusus | ⚠️ Manual |
| Runtime | Node.js, Bun, Deno, Cloudflare | Hanya Node.js | Hanya Node.js |
| Ukuran & kontrol | Ringan, fleksibel | Besar, opiniated | Berat & legacy |

---

## 🧩 Ekosistem Pendukung

* 🧠 **Oslo** – library resmi untuk hashing & crypto
    
* 🧰 **@lucia-auth/adapter-\*** – integrasi dengan ORM/DB populer
    
* 🔗 **@lucia-auth/oauth** – provider login sosial
    
* 📦 **tRPC / Hono / Elysia** – backend framework yang cocok
    

---

## 🧾 Kesimpulan

Lucia menawarkan keseimbangan sempurna antara **kemudahan**, **fleksibilitas**, dan **keamanan**.

Jika kamu ingin sistem auth yang:

* Clean, type-safe, dan tidak bergantung framework
    
* Cocok untuk Bun, Hono, atau Edge Function
    
* Mendukung OAuth tanpa ribet
    
* Bisa diatur penuh sesuai kebutuhan
    

… maka **Lucia** adalah pilihan terbaik di ekosistem TypeScript modern.

---

## 📚 Rangkuman Cepat

| Aspek | Deskripsi |
| --- | --- |
| Nama | Lucia Auth |
| Bahasa | TypeScript |
| Arsitektur | Session-based (bukan JWT) |
| ORM Support | Drizzle, Prisma, LibSQL, PlanetScale, dkk |
| OAuth | Google, GitHub, Discord, Facebook, dkk |
| Keamanan | Argon2id, Cookie Secure, HttpOnly |
| Runtime | Node.js, Bun, Deno, Cloudflare |
| Filosofi | Simple. Type-safe. Framework-agnostic. |

---
