FaizBlog LogoFaizBlog
Back to all articles
cloudflareworkersproxyapi-keytutorial

Membuat Proxy API dengan Cloudflare Workers (Sembunyikan API Key)

Bikin proxy API pakai Cloudflare Workers untuk sembunyikan API key dari frontend, bypass CORS, dan rate limit dari edge.

AI Insights

Generate a summary and suggested tags for this post.

Punya API key OpenAI / Google Maps / Stripe yang ga boleh ditaruh di frontend? Bikin proxy API pakai Cloudflare Workers — API key aman di server, frontend cuma hit proxy.

Proxy API dengan Cloudflare Workers

Kenapa Butuh Proxy API?

MasalahSolusi Proxy
API key kepampang di frontendSimpan di Worker env
CORS error dari API pihak ke-3Worker set CORS header sendiri
Butuh rate limit per userCek di Worker sebelum forward
Butuh transform responseModif JSON di Worker
Butuh cachePakai Cache API atau KV

Contoh: Proxy OpenAI API

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname !== "/chat") return new Response("Not found", { status: 404 });

    const body = await request.json();

    const openaiRes = await fetch("https://api.openai.com/v1/chat/completions", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${env.OPENAI_KEY}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(body)
    });

    return new Response(openaiRes.body, {
      status: openaiRes.status,
      headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
      }
    });
  }
};

Simpan API Key sebagai Secret

JANGAN taruh API key di wrangler.toml! Pakai secret:

npx wrangler secret put OPENAI_KEY
# Paste API key

Secret otomatis available di env.OPENAI_KEY — tidak muncul di source code.

Bypass CORS (Fetch dari Frontend)

app.use("/*", cors({
  origin: ["https://blog.izz.my.id", "http://localhost:3000"],
  allowMethods: ["GET", "POST"],
}));

Rate Limit per IP

Pakai KV untuk track request:

const ip = request.headers.get("cf-connecting-ip");
const key = `rate:${ip}`;
const count = parseInt(await env.KV.get(key) || "0");

if (count >= 100) {
  return new Response("Rate limit exceeded", { status: 429 });
}

await env.KV.put(key, String(count + 1), { expirationTtl: 3600 });

Cache Response (Hemat Kuota API)

const cache = caches.default;
const cacheKey = new Request(url.toString(), request);
let response = await cache.match(cacheKey);

if (!response) {
  response = await fetch("https://api.example.com/data");
  response = new Response(response.body, response);
  response.headers.set("Cache-Control", "max-age=300"); // 5 menit
  await cache.put(cacheKey, response.clone());
}

return response;

Contoh Lain: Proxy Google Maps API

app.get("/geocode", async (c) => {
  const address = c.req.query("address");
  const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${c.env.GMAPS_KEY}`;
  const res = await fetch(url);
  return res;
});

Frontend call: fetch("/geocode?address=Jakarta") — tanpa API key.

Security Best Practices

  • ✅ Selalu pakai wrangler secret put untuk API key
  • ✅ Whitelist CORS origin (jangan * di production)
  • ✅ Tambahkan rate limit
  • ✅ Validasi input dari user
  • ✅ Log request untuk audit (via console.log → tail dengan wrangler tail)

Kesimpulan

Proxy API pakai Cloudflare Workers = solusi elegan untuk sembunyikan API key + bypass CORS + rate limit + cache — semua di satu tempat. Free tier 100rb request/hari cukup untuk mayoritas project.