Skip to main content

Command Palette

Search for a command to run...

Mengelola Cookies di Hono: Development, Testing, & Produksi

Updated
5 min read
Mengelola Cookies di Hono: Development, Testing, & Produksi
A

I am an enthusiastic researcher and developer with a passion for using technology to innovate in business and education.

Cookies adalah bagian fundamental dari aplikasi web modern. Mereka digunakan untuk mengelola sesi login, menyimpan preferensi pengguna, dan melacak aktivitas. Namun, mengonfigurasi cookies dengan benar di berbagai lingkungan—mulai dari localhost untuk development, server produksi dengan subdomain, hingga lingkungan testing otomatis—seringkali menjadi tantangan.

Artikel ini akan memandu Anda secara lengkap dan mudah untuk mengelola cookies di Hono, dengan contoh kode yang siap diimplementasikan.


Sebelum masuk ke kode, mari kita pahami "aturan main" atau atribut utama dari sebuah cookie. Memahami ini adalah kunci untuk konfigurasi yang benar.

  • httpOnly: Jika true, cookie tidak bisa diakses oleh JavaScript sisi klien (document.cookie). Ini adalah pertahanan wajib terhadap serangan XSS.

  • secure: Jika true, cookie hanya akan dikirim melalui koneksi HTTPS. Wajib di lingkungan produksi.

  • path: Menentukan URL path mana yang bisa menerima cookie. Mengaturnya ke / membuatnya tersedia di seluruh situs Anda.

  • domain: Mengontrol subdomain mana yang bisa menerima cookie. Ini adalah kunci untuk arsitektur dengan API di subdomain terpisah.

  • sameSite: Perlindungan utama terhadap serangan CSRF.

    • Strict: Paling ketat, cookie hanya dikirim jika permintaan berasal dari situs yang sama persis.

    • Lax: Default yang seimbang. Cookie dikirim saat navigasi dari situs eksternal (misal: klik link), tapi tidak pada sub-request seperti POST dari situs lain.

    • None: Paling longgar. Cookie dikirim di semua konteks lintas situs, tetapi wajib digunakan bersama secure: true.

  • maxAge: Menentukan masa aktif cookie dalam detik.


## 1. Lingkungan Development (Lokal) 💻

Di lingkungan development, prioritas kita adalah kemudahan dan kecepatan. Kita biasanya bekerja di localhost, di mana frontend dan backend dianggap berasal dari "situs yang sama" (same-site).

Tujuan: Membuat cookie berfungsi di localhost tanpa konfigurasi yang rumit.

Konfigurasi Kunci:

  • domain: Biarkan kosong. Browser akan otomatis mengaturnya ke localhost.

  • sameSite: Lax adalah pilihan terbaik. Aman dan berfungsi tanpa masalah.

  • secure: Boleh false karena kita sering bekerja dengan http://localhost.

Contoh Implementasi:

Kita akan menggunakan helper setCookie dan getCookie dari hono/cookie.

TypeScript

// src/index.ts
import { Hono } from 'hono';
import { getCookie, setCookie } from 'hono/cookie';

const app = new Hono();

app.get('/login-dev', (c) => {
  const userInfo = { userId: '123', name: 'Dev User' };

  setCookie(c, 'session', JSON.stringify(userInfo), {
    path: '/',
    sameSite: 'Lax', // Pilihan aman dan mudah untuk localhost
    httpOnly: true,
    maxAge: 60 * 60 * 24, // 1 hari
  });

  return c.json({ message: 'Login successful for development' });
});

app.get('/profile-dev', (c) => {
  const session = getCookie(c, 'session');

  if (!session) {
    return c.json({ error: 'Not authenticated' }, 401);
  }

  return c.json({ data: JSON.parse(session) });
});

export default app;

## 2. Lingkungan Produksi 🌐

Di produksi, keamanan dan fungsionalitas di domain nyata adalah prioritas utama. Skenario umum adalah frontend di app.yourdomain.com dan backend di api.yourdomain.com.

Tujuan: Memastikan cookie aman dan bisa dibagikan antar subdomain.

Konfigurasi Kunci:

  • domain: Wajib diatur ke domain induk dengan titik di depan: .yourdomain.com.

  • sameSite: Wajib None agar browser mau mengirim cookie dari app ke api.

  • secure: Wajib true karena SameSite=None memerlukannya dan untuk keamanan umum.

Contoh Implementasi:

TypeScript

// src/index.ts
// ... (lanjutan dari kode sebelumnya)

app.post('/login-prod', (c) => {
  const userInfo = { userId: '456', role: 'admin' };

  setCookie(c, 'session', JSON.stringify(userInfo), {
    path: '/',
    domain: '.yourdomain.com', // Penting untuk berbagi antar subdomain
    sameSite: 'None',          // Wajib untuk permintaan cross-subdomain
    secure: true,              // Wajib untuk SameSite=None dan HTTPS
    httpOnly: true,
    maxAge: 60 * 60 * 24 * 7, // 7 hari
  });

  return c.json({ message: 'Login successful for production' });
});

## 3. Lingkungan Testing (Otomatis) 🧪

Dalam testing otomatis (misalnya dengan Vitest atau Jest), kita tidak memiliki browser sungguhan. Kita tidak menguji apakah browser menyimpan cookie, melainkan apakah server kita mengirim header Set-Cookie yang benar.

Tujuan: Memverifikasi bahwa respons dari server berisi header Set-Cookie dengan atribut yang tepat.

Konsep Kunci:

Kita akan membuat request ke aplikasi Hono kita dalam script tes, lalu memeriksa header Set-Cookie pada objek respons.

Contoh Implementasi (dengan Vitest):

TypeScript

// src/index.test.ts
import { describe, it, expect } from 'vitest';
import app from './index'; // Impor aplikasi Hono Anda

describe('Cookie Handling', () => {

  it('should set the correct development cookie header', async () => {
    const res = await app.request('/login-dev');

    // Ambil header Set-Cookie
    const cookieHeader = res.headers.get('Set-Cookie');

    // Verifikasi bahwa headernya ada dan berisi atribut yang benar
    expect(cookieHeader).not.toBeNull();
    expect(cookieHeader).toContain('session=');
    expect(cookieHeader).toContain('Path=/');
    expect(cookieHeader).toContain('SameSite=Lax');
    expect(cookieHeader).toContain('HttpOnly');
  });

  it('should set the correct production cookie header', async () => {
    const res = await app.request('/login-prod', { method: 'POST' });
    const cookieHeader = res.headers.get('Set-Cookie');

    expect(cookieHeader).not.toBeNull();
    expect(cookieHeader).toContain('Domain=.yourdomain.com');
    expect(cookieHeader).toContain('SameSite=None');
    expect(cookieHeader).toContain('Secure');
  });
});

## Implementasi Gabungan: Praktik Terbaik

Mengelola konfigurasi berbeda secara manual sangat tidak efisien. Solusinya adalah menggunakan variabel lingkungan (process.env.NODE_ENV) untuk mengatur atribut cookie secara dinamis.

Buat sebuah fungsi helper untuk membungkus logika ini.

TypeScript

// src/utils/cookies.ts
import { Context } from 'hono';
import { setCookie as honoSetCookie } from 'hono/cookie';

type CookieOptions = {
  path?: string;
  domain?: string;
  sameSite?: 'Strict' | 'Lax' | 'None';
  secure?: boolean;
  httpOnly?: boolean;
  maxAge?: number;
};

export function setAppCookie(c: Context, name: string, value: string) {
  const isProd = process.env.NODE_ENV === 'production';

  const options: CookieOptions = {
    path: '/',
    httpOnly: true,
    // Atur berdasarkan lingkungan
    domain: isProd ? '.yourdomain.com' : undefined,
    sameSite: isProd ? 'None' : 'Lax',
    secure: isProd,
    maxAge: 60 * 60 * 24 * 7, // 7 hari
  };

  honoSetCookie(c, name, value, options);
}

Cara Menggunakannya:

Sekarang, Anda bisa menggunakan satu fungsi ini di seluruh aplikasi Anda.

TypeScript

// src/index.ts
import { setAppCookie } from './utils/cookies';

// ...
app.post('/auth/login', (c) => {
    const user = { id: '789', username: 'unified-user' };
    setAppCookie(c, 'session', JSON.stringify(user));
    return c.json({ message: 'Login handled dynamically!' });
});

Untuk logout, gunakan helper deleteCookie. Pastikan Anda menyertakan path dan domain yang sama agar browser tahu cookie mana yang harus dihapus.

TypeScript

import { deleteCookie } from 'hono/cookie';

app.post('/auth/logout', (c) => {
    const isProd = process.env.NODE_ENV === 'production';

    deleteCookie(c, 'session', {
        path: '/',
        domain: isProd ? '.yourdomain.com' : undefined,
    });

    return c.json({ message: 'Logged out' });
});

Dengan mengikuti panduan ini, Anda dapat mengelola cookies di Hono secara efektif, aman, dan mudah di-maintain di semua lingkungan aplikasi Anda.

More from this blog

F

Finlup ID | Sharing dunia teknologi dan coding

206 posts

Membedah Tren dan Teknologi yang Mengubah Dunia.