FaizBlog LogoFaizBlog
Back to all articles
cloudflareworkersauthjwttutorial

Membuat Authentication Sederhana di Cloudflare Workers (API Key, Basic, JWT)

Panduan lengkap 3 metode autentikasi di Cloudflare Workers — API Key, HTTP Basic Auth, dan JWT — dari yang paling simple sampai production-ready.

AI Insights

Generate a summary and suggested tags for this post.

Butuh proteksi endpoint di Cloudflare Workers? Ada 3 metode populer dari yang paling simple ke paling secure: API Key, HTTP Basic Auth, dan JWT.

Authentication di Cloudflare Workers

Perbandingan 3 Metode

MetodeKompleksitasCocok Untuk
API Key⭐ SimpleServer-to-server, internal tools
Basic Auth⭐⭐ MediumAdmin panel simple, dev tools
JWT⭐⭐⭐ ComplexUser login, mobile app, SPA

1. API Key Authentication

Paling simple — cek header x-api-key.

Simpan API Key sebagai Secret

npx wrangler secret put API_KEY
# Paste key, misal: sk_live_abc123xyz

Middleware

import { Hono } from "hono";
const app = new Hono();

app.use("/api/*", async (c, next) => {
  const key = c.req.header("x-api-key");
  if (key !== c.env.API_KEY) {
    return c.json({ error: "Invalid API key" }, 401);
  }
  await next();
});

app.get("/api/data", (c) => c.json({ secret: "value" }));

export default app;

Client Call

curl https://myworker.workers.dev/api/data \
  -H "x-api-key: sk_live_abc123xyz"

2. HTTP Basic Authentication

Pakai username + password base64-encoded di header Authorization.

Pakai Hono built-in

import { basicAuth } from "hono/basic-auth";

app.use("/admin/*", basicAuth({
  username: "admin",
  password: "secret123",
}));

app.get("/admin/dashboard", (c) => c.text("Admin panel"));

Browser akan popup form login otomatis.

Manual (Kalau Butuh Multi User)

app.use("/admin/*", async (c, next) => {
  const auth = c.req.header("authorization");
  if (!auth?.startsWith("Basic ")) {
    return new Response("Unauthorized", {
      status: 401,
      headers: { "WWW-Authenticate": 'Basic realm="Admin"' }
    });
  }

  const decoded = atob(auth.split(" ")[1]);
  const [user, pass] = decoded.split(":");

  const users = { admin: "s3cr3t", faiz: "myp4ss" };
  if (users[user] !== pass) return c.text("Wrong", 401);

  await next();
});

3. JWT Authentication (Production-Ready)

JWT = JSON Web Token — token signed yang bisa berisi user data.

Install & Setup

npm install hono

Hono sudah include JWT built-in.

Login Endpoint (Issue Token)

import { Hono } from "hono";
import { sign } from "hono/jwt";

const app = new Hono();

app.post("/login", async (c) => {
  const { email, password } = await c.req.json();

  // Cek user dari database
  const user = await getUser(email);
  if (!user || !verifyPassword(password, user.password_hash)) {
    return c.json({ error: "Invalid credentials" }, 401);
  }

  const token = await sign({
    sub: user.id,
    email: user.email,
    exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 jam
  }, c.env.JWT_SECRET);

  return c.json({ token });
});

Protect Endpoint

import { jwt } from "hono/jwt";

app.use("/api/*", async (c, next) => {
  const jwtMiddleware = jwt({ secret: c.env.JWT_SECRET });
  return jwtMiddleware(c, next);
});

app.get("/api/me", (c) => {
  const payload = c.get("jwtPayload");
  return c.json({ user: payload });
});

Client Call

# Login
curl -X POST https://myworker.workers.dev/login \
  -H "Content-Type: application/json" \
  -d '{"email":"faiz@example.com","password":"..."}'

# Response: { "token": "eyJhbGc..." }

# Pakai token
curl https://myworker.workers.dev/api/me \
  -H "Authorization: Bearer eyJhbGc..."

Struktur JWT

JWT = 3 bagian dipisah titik:

header.payload.signature

Contoh decoded:

// Header
{ "alg": "HS256", "typ": "JWT" }

// Payload
{ "sub": "user-123", "email": "faiz@x.com", "exp": 1735689600 }

// Signature — HMAC dari header+payload pakai secret

Password Hashing di Workers

Cloudflare Workers ga support bcrypt (native module). Pakai PBKDF2 via Web Crypto:

async function hashPassword(password: string) {
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const encoded = new TextEncoder().encode(password);
  const key = await crypto.subtle.importKey("raw", encoded, "PBKDF2", false, ["deriveBits"]);
  const bits = await crypto.subtle.deriveBits(
    { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256" },
    key, 256
  );
  return btoa(String.fromCharCode(...salt, ...new Uint8Array(bits)));
}

Security Checklist

  • ✅ Simpan JWT_SECRET pakai wrangler secret put
  • ✅ Set expiration (exp) di JWT — jangan token seumur hidup
  • ✅ Pakai HTTPS only (default Cloudflare)
  • ✅ Hash password pakai PBKDF2 / Argon2
  • ✅ Rate limit endpoint /login
  • ✅ Jangan simpan sensitive data di JWT payload (bisa didecode)

Kesimpulan

KebutuhanPilih
Internal API antar serverAPI Key
Admin panel simpleBasic Auth
User login (web/mobile app)JWT

Rekomendasi: untuk kebanyakan aplikasi user-facing, pakai JWT — standard industry, portable, dan support di semua platform.