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.

Kenapa Butuh Proxy API?
| Masalah | Solusi Proxy |
|---|---|
| API key kepampang di frontend | Simpan di Worker env |
| CORS error dari API pihak ke-3 | Worker set CORS header sendiri |
| Butuh rate limit per user | Cek di Worker sebelum forward |
| Butuh transform response | Modif JSON di Worker |
| Butuh cache | Pakai 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 keySecret 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 putuntuk 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.
