Design wechseln

API Key im Frontend offengelegt? Workers-Proxy schützt Secrets in 5 Minuten – 100.000 kostenlose Requests täglich

Ich habe ein kleines Tool gebaut, das die ChatGPT-API aufruft – und den API Key direkt im Frontend-Code hinterlegt. Am nächsten Tag war mein Konto um über 300 Euro missbraucht worden: Tausende Aufrufe über Nacht. Umgebungsvariablen helfen auch nicht – Vite- oder Webpack-Env-Variablen landen beim Build in JS-Dateien; im Network-Panel sieht man alle Requests inklusive Key.

Die klassische Lösung: Backend-Server als Proxy. Das kostet Geld und erfordert Umgebung, SSL-Zertifikat, CORS-Konfiguration. Cloudflare Workers deployen in 5 Minuten einen API-Proxy; der Key liegt in Server-Umgebungsvariablen, das Frontend berührt ihn nie. Kostenlos, 100.000 Anfragen pro Tag. Dieser Artikel zeigt den Aufbau.

Warum der API Key nicht ins Frontend gehört

Frontend-Code ist vollständig transparent

Viele glauben, .env oder Vités import.meta.env seien sicher. Das ist nur ein Entwicklungskomfort – nach dem Build werden alle Env-Variablen in JS-Dateien hardcodiert.

Probieren Sie es: Öffnen Sie ein Frontend-Projekt in Produktion, F12 → Network, Seite neu laden. Alle API-Requests inklusive Header, Body und URL-Parameter sind sichtbar.

Obfuscation und Minifizierung machen Code nur schwerer lesbar – der API-Aufruf muss den echten Key senden, der lässt sich nicht verschleiern. Verschlüsselung? Ent- und Verschlüsselung laufen im Frontend – der Nutzer sieht alles.

Kurz: Frontend läuft im Browser des Nutzers. Alles, was Sie tun können, kann er auch. Das ist nicht lösbar.

Was Missbrauch kostet

Ich dachte: Wer soll schon meinen Code nach Keys durchsuchen? Im Internet gibt es Leute, die genau das tun.

Auf GitHub scannen Tools automatisch Repos nach exponierten API Keys. Gefundene Keys werden für eigene Aufrufe oder Weiterverkauf genutzt. OpenAI rechnet pro Token ab – ein Missbrauch über Nacht kann Hunderte Euro kosten, im Extremfall Tausende.

In einem Entwicklerforum las ich: Jemand hatte den Key im Frontend einer AI-Chat-Seite – nach dem Leak explodierte die Rechnung auf über 2.000 US-Dollar im Monat. Die Beschwerde ging durch, aber der Stress blieb.

Nicht nur OpenAI: Google Maps, Wetter-APIs, Übersetzungs-APIs – alles Pay-per-Use ist gefährdet.

Probleme klassischer Lösungen

Die übliche Empfehlung: Backend-Proxy. Klingt einfach, ist es oft nicht:

  • Kosten: Günstigste Cloud-Server (Alibaba, Tencent Light) kosten 50–100 Euro/Monat – für kleine Projekte spürbar.
  • Komplexität: Node.js, Nginx, SSL, HTTPS, CORS – einen halben Tag nur fürs Verstehen.
  • Wartung: Updates, Monitoring, Neustarts bei Ausfall – für Kleinstprojekte zu viel Aufwand.

Serverless der großen Anbieter spart Geld, ist aber oft komplexer, mit Cold Start und weniger freundlicher Doku. Ich habe es mehrfach ohne Erfolg versucht.

API-Gateways sind Enterprise-Produkte – für Einzelentwickler zu hoch die Hürde.

Vorteile von Cloudflare Workers

Kostenlos und leistungsstark

Das Free-Tier: 100.000 Anfragen pro Tag. Für persönliche Projekte reicht das. Mein Tool: ein paar Hundert Aufrufe täglich – weit unter dem Limit.

100.000/Tag
Free-Kontingent
Für persönliche Projekte mehr als genug
5 Min.
Deployment-Zeit
Von Erstellung bis Live
50–100 €/Monat gespart
Kostenvergleich
Gegenüber eigenem Server

Cloudflare betreibt über 200 Rechenzentren weltweit – Ihr Code läuft automatisch am Edge. Nutzer werden zum nächsten Knoten geroutet, Antwortzeiten sind kurz. Anders als bei einem Server in einer Region.

Wichtig: Workers haben praktisch kein Cold-Start-Problem. Bei AWS Lambda kann nach langer Pause der nächste Aufruf Sekunden dauern. Workers antworten in Millisekunden – ähnlich wie ein klassischer Server.

Extrem einfaches Deployment

Beim ersten Mal: Von Registrierung bis Live in 5 Minuten – kein Marketing.

Kein Server-Setup, kein Node.js oder Nginx, kein SSL-Antrag (Workers liefern HTTPS). Sie:

  1. Schreiben Code (eine JS-Datei, wenige Dutzend Zeilen)
  2. Führen aus: wrangler publish
  3. Fertig

Cloudflare vergibt eine Domain wie your-worker.your-subdomain.workers.dev. Eigene Domain? In der Konsole binden – ohne Extra-Konfiguration.

Vergleich klassisch: Server kaufen → Umgebung → Code → Nginx → Zertifikat → Deploy → Test – allein die Liste ist ermüdend.

CORS natürlich gelöst

Frontend-Aufrufe an Drittanbieter-APIs scheitern oft an CORS: Access to fetch at 'xxx' from origin 'yyy' has been blocked by CORS policy.

Browser blockieren Cross-Origin-Requests. Die API müsste CORS-Header setzen – bei fremden APIs ändern Sie das nicht.

Mit Workers als Proxy:

  • Frontend ruft Ihre Worker-URL auf (z. B. https://api.yourdomain.com)
  • Worker ruft die Drittanbieter-API auf
  • Worker setzt CORS-Header in der Antwort

Für den Browser: Same-Origin. Für die API: Server-zu-Server, kein CORS-Problem.

Bei Amap (Gaode) Maps API hatte ich dauernd CORS-Fehler – mit Workers-Proxy zwei Zeilen Code, erledigt.

Praxis: Ihren ersten API-Proxy bauen

Genug Theorie – Schritt für Schritt, am Beispiel OpenAI-API; andere APIs funktionieren ähnlich.

Schritt 1: Umgebung vorbereiten

1. Cloudflare-Konto registrieren

Auf cloudflare.com registrieren – Free reicht. E-Mail bestätigen.

2. Wrangler CLI installieren

Wrangler ist das offizielle CLI für Workers.

npm install -g wrangler

Ohne Node.js: nodejs.org installieren.

3. Anmelden

wrangler login

Öffnet den Browser zur Autorisierung – zustimmen, danach kann die CLI Ihre Workers verwalten.

Schritt 2: Worker-Projekt erstellen

wrangler init openai-proxy

Fragen:

  • „Would you like to use TypeScript?” → No (außer Sie kennen TS)
  • „Would you like to create a new Worker?” → Yes
  • „Would you like to install dependencies?” → Yes

Projektstruktur:

openai-proxy/
├── src/
│   └── index.js       # Code hier
├── wrangler.toml      # Konfiguration
└── package.json

Schritt 3: Proxy-Code schreiben

src/index.js öffnen, Standardcode ersetzen:

export default {
  async fetch(request, env) {
    // Nur POST erlauben
    if (request.method !== 'POST') {
      return new Response('Method not allowed', { status: 405 });
    }
    // OpenAI API Key aus Umgebungsvariable
    const apiKey = env.OPENAI_API_KEY;
    if (!apiKey) {
      return new Response('API Key not configured', { status: 500 });
    }
    try {
      const body = await request.json();
      const response = await fetch('https://api.openai.com/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${apiKey}`,  // Server-Key
        },
        body: JSON.stringify(body),
      });
      const data = await response.json();
      return new Response(JSON.stringify(data), {
        status: response.status,
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'POST',
          'Access-Control-Allow-Headers': 'Content-Type',
        },
      });
    } catch (error) {
      return new Response(JSON.stringify({ error: error.message }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
      });
    }
  },
};

Ablauf:

  1. POST vom Frontend empfangen
  2. Echten API Key aus Env lesen (Frontend sieht ihn nie)
  3. OpenAI-API aufrufen
  4. Antwort mit CORS-Headern zurückgeben

Schritt 4: Secrets konfigurieren (API Key speichern)

Der Key gehört nicht in den Code – Cloudflare Secrets verschlüsseln ihn.

wrangler secret put OPENAI_API_KEY

Key einfügen, Enter. Verschlüsselt auf Cloudflare – in der Konsole kein Klartext. Im Code: env.OPENAI_API_KEY.

Lokale Entwicklung

.dev.vars im Projektroot:

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx

Nur lokal – nicht in Git committen. In .gitignore:

.dev.vars

Schritt 5: Lokal testen

wrangler dev

Server unter http://localhost:8787. Mit Postman oder Frontend:

fetch('http://localhost:8787', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'gpt-3.5-turbo',
    messages: [{ role: 'user', content: 'Hello!' }],
  }),
})
  .then(res => res.json())
  .then(data => console.log(data));

Normale OpenAI-Antwort? Proxy funktioniert.

Schritt 6: Produktion deployen

wrangler publish

Nach Sekunden eine URL wie:

https://openai-proxy.your-subdomain.workers.dev

Frontend-API-URL darauf umstellen – der Key bleibt serverseitig.

Eigene Domain: Cloudflare-Konsole → Worker → Settings → Triggers → Add Custom Domain, z. B. api.yourdomain.com, DNS wie angezeigt.

Fortgeschrittene Tipps und Best Practices

Der Basis-Code läuft – hier Optimierungen.

Missbrauch des Proxys verhindern

Der Worker ist öffentlich – wer die URL kennt, kann aufrufen. Missbrauch frisst das Free-Kontingent oder verursacht Kosten.

Einfache Token-Validierung

export default {
  async fetch(request, env) {
    const token = request.headers.get('X-API-Token');
    if (token !== env.MY_SECRET_TOKEN) {
      return new Response('Unauthorized', { status: 401 });
    }
    // ... Proxy-Logik
  },
};

wrangler secret put MY_SECRET_TOKEN setzen. Frontend:

fetch('https://your-worker.workers.dev', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Token': 'your-secret-token',
  },
  body: JSON.stringify(data),
});

Der Token ist im Frontend sichtbar – aber eine zusätzliche Hürde. Regelmäßig rotieren oder pro Nutzer unterschiedliche Tokens.

IP-/Origin-Whitelist

Nur bestimmte Domains:

const allowedOrigins = ['https://yourdomain.com', 'http://localhost:3000'];
const origin = request.headers.get('Origin');
if (!allowedOrigins.includes(origin)) {
  return new Response('Forbidden', { status: 403 });
}

Mehrere APIs unterstützen

Über Pfade trennen:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname.startsWith('/openai')) {
      return proxyOpenAI(request, env);
    } else if (url.pathname.startsWith('/maps')) {
      return proxyMaps(request, env);
    } else {
      return new Response('Not found', { status: 404 });
    }
  },
};
async function proxyOpenAI(request, env) {
  // OpenAI-Logik
}
async function proxyMaps(request, env) {
  // Maps-Logik
}

Ein Worker, mehrere APIs.

OPTIONS-Requests (vollständiges CORS)

Vor Cross-Origin-POST sendet der Browser OPTIONS:

export default {
  async fetch(request, env) {
    if (request.method === 'OPTIONS') {
      return new Response(null, {
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type, X-API-Token',
          'Access-Control-Max-Age': '86400',
        },
      });
    }
    // ... normale Verarbeitung
  },
};

Monitoring und Debugging

In der Cloudflare-Konsole: Anfragen, Fehlerrate, Latenz.

Live-Logs: wrangler tail

wrangler tail

Alle Requests und console.log()-Ausgaben im Terminal.

Häufige Fragen

Free-Kontingent aufgebraucht?

100.000/Tag reicht für die meisten persönlichen Projekte. Meins: monatelang nie überschritten.

Wenn nicht: Paid ab 5 US-Dollar/Monat für 10 Mio. Anfragen – günstiger als ein eigener Server.

Sind Workers stabil?

Cloudflare ist einer der größten CDN-Anbieter. Seit Monaten bei mir ohne Ausfall. SLA 99,99 % – oft zuverlässiger als Self-Hosting.

Eigene Domain?

Ja – in der Konsole binden, DNS anpassen, ~5 Minuten, HTTPS automatisch.

Geschwindigkeit in China?

Cloudflare hat Knoten in China – oft 100–300 ms, schneller als direkter Aufruf aus dem Ausland. Für maximale Inland-Performance: lokale Serverless (z. B. Alibaba FC) – komplexer.

Andere Sprachen als JavaScript?

Primär JS/TypeScript. Andere Sprachen via WebAssembly möglich – höhere Hürde. Für API-Proxy reicht JavaScript.

Ist das wirklich sicher?

Ja, solange der Key nicht in der Antwort ans Frontend geht. Secrets verschlüsselt, Konsole ohne Klartext. Trotzdem Zugriffskontrolle gegen Missbrauch – Token, Origin-Whitelist.

Fazit

API-Key-Leaks haben mich lange beschäftigt – Risiko akzeptieren oder Server kaufen schien die Wahl.

Cloudflare Workers zeigen: 5 Minuten Deploy, kostenlos, Key serverseitig, CORS mitgelöst – für persönliche Projekte oft die beste Option.

Wenn Ihr Projekt Drittanbieter-APIs braucht: diese Methode ausprobieren. Die Schritte oben reichen; in einer halben Stunde sind Sie durch.

Code zum Kopieren und Anpassen ist enthalten. Bei Fragen: Cloudflare-Doku oder Kommentare.

Nach dem Deploy: Zugriffskontrolle nicht vergessen – Token oder Domain-Einschränkung sind einfach und wirksam.

Jetzt Cloudflare-Konto anlegen und ausprobieren!

API-Proxy mit Cloudflare Workers zum Schutz von API-Keys

Vom Verständnis der API-Key-Risiken bis zum 5-Minuten-Workers-Deploy – mit Code und Sicherheits-Best-Practices

⏱️ Estimated time: 5 min

  1. 1

    Step 1: API-Key-Risiken und Probleme klassischer Lösungen verstehen

    API-Key-Sicherheit im Frontend:
    • Frontend-Code ist transparent – Env-Variablen werden beim Build in JS hardcodiert
    • Im Network-Panel sind alle Requests inklusive API Key sichtbar
    • Obfuscation hilft nur beim Lesen – der echte Key muss mitgesendet werden
    • Verschlüsselung scheitert, weil Ent-/Entschlüsselung im Frontend läuft

    Kosten des Missbrauchs:
    • GitHub-Tools scannen Repos nach exponierten Keys
    • Gefundene Keys werden missbraucht oder weiterverkauft
    • OpenAI: pro Token – eine Nacht kann Hunderte Euro kosten
    • AI-Chat-Seite mit Frontend-Key: Rechnung über 2.000 US-Dollar im Monat

    Probleme klassischer Lösungen:
    • Kosten: Cloud-Server 50–100 Euro/Monat
    • Komplexität: Node.js, Nginx, SSL, CORS – halber Tag Setup
    • Wartung: Updates, Monitoring, Neustarts
  2. 2

    Step 2: Vorteile von Cloudflare Workers kennenlernen

    Kostenlos und leistungsstark:
    • 100.000 Anfragen/Tag im Free-Tier
    • Für persönliche Projekte mehr als genug
    • 200+ Edge-Knoten, Latenz oft 100–300 ms

    API-Key-Sicherheit:
    • Key in Server-Umgebungsvariablen
    • Secrets verschlüsselt, kein Klartext in der Konsole
    • Frontend berührt den Key nie

    Weitere Vorteile:
    • CORS automatisch gelöst
    • Deployment in ~5 Minuten statt Server-Setup mit SSL und CORS
  3. 3

    Step 3: 5-Minuten-Deploy: Wrangler installieren und Worker erstellen

    Schritt 1: Wrangler CLI
    • npm install -g wrangler
    • wrangler --version zur Verifikation

    Schritt 2: Cloudflare-Login
    • wrangler login
    • Browser-Autorisierung mit „Erlauben"
    • „Successfully logged in" in der Konsole

    Schritt 3: Worker-Projekt
    • mkdir api-proxy && cd api-proxy && wrangler init
    • Standardwerte mit Enter; TypeScript optional
    • wrangler.toml, src/index.ts, package.json

    Schritt 4: API Key als Secret
    • wrangler secret put OPENAI_API_KEY
    • Key eingeben – sicher serverseitig, Frontend ohne Zugriff
  4. 4

    Step 4: Kern-Code für den API-Proxy implementieren

    Ablauf: Frontend-Request empfangen → API Key aus Env → Request an Ziel-API weiterleiten → Key in Header → Antwort ans Frontend. Unterstützt GET/POST usw. Beispiel: export default { async fetch(request, env) { const url = new URL(request.url); const targetUrl = url.searchParams.get('url'); if (!targetUrl) { return new Response('Missing url parameter', { status: 400 }); } const apiKey = env.OPENAI_API_KEY; const response = await fetch(targetUrl, { method: request.method, headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: request.method !== 'GET' ? await request.text() : undefined }); return new Response(response.body, { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' } }); } }. Schritte: 1) Ziel-URL aus Parameter; 2) Key aus Env; 3) Weiterleitung mit Authorization; 4) CORS-Header in der Antwort.
  5. 5

    Step 5: Deploy und Frontend-Aufruf

    Deploy: wrangler deploy im Projektverzeichnis – URL wie your-worker-name.your-subdomain.workers.dev. Frontend: Statt fetch('https://api.openai.com/v1/chat/completions', { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }) → fetch('https://your-worker-name.your-subdomain.workers.dev?url=https://api.openai.com/v1/chat/completions'). Key bleibt serverseitig. Monitoring: Cloudflare-Konsole für Anfragen, Fehler, Latenz; wrangler tail für Live-Logs.
  6. 6

    Step 6: Sicherheits-Best-Practices und FAQ

    Best Practices: 1) Key nur als Secret, nie hardcoden (wrangler secret put); 2) Rate Limiting gegen Missbrauch; 3) Origin/Referer prüfen; 4) Logs mit wrangler tail; 5) Key bei Anomalien rotieren. FAQ: Free-Kontingent reicht meist; Paid 5 USD/Monat für 10 Mio. Requests. Stabil: 99,99 % SLA. Eigene Domain in ~5 Minuten mit Auto-HTTPS. China: 100–300 ms typisch. Sicher, solange Key nicht in der Response – plus Zugriffskontrolle.

FAQ

Warum ist ein API Key im Frontend unsicher? Warum Missbrauch?
Transparenz des Frontend-Codes:
• .env oder Vites import.meta.env sind nach dem Build in JS sichtbar
• F12 → Network zeigt alle Requests inklusive Key
• Obfuscation ändert nichts am mitgesendeten Key
• Verschlüsselung im Frontend ist für den Nutzer durchschaubar
• Frontend im Browser – keine echte Geheimhaltung

Kosten des Missbrauchs:
• Automatische GitHub-Scans nach Keys
• Missbrauch oder Weiterverkauf
• OpenAI pro Token – Hunderte Euro über Nacht möglich
• Frontend-Key in AI-Chat: Rechnung über 2.000 US-Dollar
• Auch Google Maps, Wetter, Übersetzung – alles Pay-per-Use gefährdet
Welche Vorteile hat Cloudflare Workers? Warum diese Wahl?
Kostenlos und performant:
• 100.000 Anfragen/Tag Free
• Für Kleinstprojekte ausreichend
• 200+ Knoten, ~100–300 ms Latenz

Key serverseitig:
• Secrets verschlüsselt, Frontend ohne Zugriff
• CORS ohne Extra-Konfiguration

Deployment in 5 Minuten:
• Kein Server, SSL, Nginx-Setup

Klassische Nachteile:
• Server 50–100 Euro/Monat
• Komplexes Setup und Wartung
Wie baut man einen API-Proxy mit Cloudflare Workers?
5-Minuten-Ablauf:

Schritt 1: npm install -g wrangler, wrangler --version
Schritt 2: wrangler login, Browser-Autorisierung
Schritt 3: mkdir api-proxy, cd, wrangler init
Schritt 4: wrangler secret put OPENAI_API_KEY

Kern-Code:
• Request → Key aus Env → Weiterleitung → Authorization-Header → Antwort + CORS
• GET/POST unterstützt; Ziel-URL aus Parameter

Deploy: wrangler deploy → Worker-URL
Frontend: API-URL auf Worker umstellen – Key bleibt serverseitig
Reicht das Free-Kontingent? Was wenn es aufgebraucht ist?
Free-Kontingent:
• 100.000 Anfragen/Tag
• Für persönliche Projekte meist genug
• Monatelang bei mir nie überschritten
• Paid: 5 USD/Monat für 10 Mio. Requests
• Günstiger als eigener Server

Monitoring:
• Cloudflare-Konsole: Anfragen, Fehler, Latenz
• wrangler tail für Live-Logs und console.log()
Stabil? Eigene Domain? Geschwindigkeit in China?
Stabilität:
• Cloudflare als großer CDN-Anbieter
• Monatelang ohne Ausfall
• SLA 99,99 %

Eigene Domain:
• In Konsole binden, DNS anpassen
• ~5 Minuten, Auto-HTTPS

China:
• Knoten vorhanden, ~100–300 ms
• Schneller als direkter Auslandsaufruf
• Für Maximal-Speed: lokale Serverless – komplexer
Ist das wirklich sicher? Welche Best Practices?
Sicherheit:
• Sicher, solange Key nicht in der Response
• Secrets verschlüsselt
• Zugriffskontrolle gegen Missbrauch nötig

Best Practices:
1) wrangler secret put, nie hardcoden
2) Rate Limiting
3) Origin/Referer einschränken
4) wrangler tail für Logs
5) Key bei Anomalien rotieren

Token oder Domain-Whitelist nach Deploy – einfach und wirksam.

8 Min. Lesezeit · Veröffentlicht am: 1. Dez. 2025 · Aktualisiert am: 4. Juli 2026

Kommentare

Melde dich mit GitHub an, um einen Kommentar zu hinterlassen

Easton BlogEaston Blog