Changer le thème

Clé API exposée côté frontend ? Proxy Workers en 5 minutes, 100 000 requêtes gratuites/jour

Easton editorial illustration: service topology model

J’ai développé un petit outil qui appelait l’API ChatGPT en mettant la clé API directement dans le code frontend. Le lendemain, mon compte avait été débité de plus de 300 yuans — des milliers d’appels en une nuit. Les variables d’environnement ne changent rien : celles de Vite ou Webpack finissent dans le bundle JS ; ouvrez l’onglet Network et la requête complète est visible.

La solution classique consiste à monter un serveur backend comme proxy, mais cela coûte de l’argent et impose la configuration de l’environnement, du certificat SSL et du CORS. Cloudflare Workers déploie un proxy API en 5 minutes : la clé API reste dans les variables d’environnement côté serveur, inaccessible au frontend. Entièrement gratuit, avec 100 000 requêtes par jour. Cet article explique comment le mettre en place.

Pourquoi la clé API ne doit pas être côté frontend

Le code frontend est entièrement transparent

Beaucoup pensent qu’un fichier .env ou import.meta.env de Vite suffit à sécuriser. En réalité, c’est un confort de développement : après le build, toutes les variables d’environnement sont intégrées dans le JS.

Pour vous en convaincre : ouvrez n’importe quel projet frontend en production, appuyez sur F12, allez dans l’onglet Network et rafraîchissez. Vous verrez toutes les requêtes API — en-têtes, corps, paramètres d’URL, tout est exposé.

Même avec obfuscation ou minification, le code devient juste moins lisible. L’appel API doit envoyer la vraie clé, impossible à masquer. Et si vous chiffrez ? Le code de chiffrement et de déchiffrement est aussi côté frontend — l’utilisateur le voit.

En bref, le frontend s’exécute dans le navigateur de l’utilisateur. Tout ce que vous pouvez faire, il peut le faire aussi. Pas de solution miracle.

Le coût d’une clé volée

Je pensais : « Qui irait gratter mon code pour voler ma clé API ? » Il existe pourtant des personnes qui s’en spécialisent sur Internet.

Des outils automatisés sur GitHub scannent les dépôts à la recherche de clés API exposées. Une fois trouvées, elles servent à abuser des API ou à être revendues. L’API OpenAI facture au token : plusieurs centaines de yuans en une nuit, c’est courant ; les cas graves dépassent le millier.

Sur un forum de développeurs, quelqu’un avait mis la clé dans une page de chat IA côté frontend. Après extraction, les appels ont fait grimper la facture mensuelle à plus de 2 000 dollars. L’appel a abouti, mais le parcours a été pénible.

Et ce n’est pas limité à OpenAI : Google Maps API, météo, traduction — toute API facturée à l’usage risque la même chose.

Les limites des solutions traditionnelles

Après avoir compris le risque, j’ai cherché comment le résoudre. La réponse habituelle : « monter un serveur backend comme proxy ».

Sur le papier, simple. En pratique :

  • Coût : un serveur cloud minimal (Alibaba Cloud, Tencent Cloud) coûte 50 à 100 yuans par mois. Pour un petit projet perso, ça pique.
  • Complexité : installer Node.js ou autre runtime, configurer Nginx en reverse proxy, obtenir un certificat SSL pour HTTPS, gérer le CORS… une demi-journée rien que pour comprendre tout ça.
  • Maintenance : mises à jour, surveillance, redémarrage en cas de panne — difficile à tenir pour un petit projet.

Les fonctions Serverless des grands clouds chinois (Alibaba Function Compute, Tencent SCF) peuvent coûter moins, mais la config est plus lourde, le cold start lent, la doc moins claire. J’ai essayé plusieurs fois sans succès.

Les API Gateway sonnent pro, mais ce sont des produits entreprise — trop hauts pour un dev solo.

Les avantages de Cloudflare Workers

Gratuit et performant

Le quota gratuit de Cloudflare Workers est de 100 000 requêtes par jour. Pour un projet perso, c’est largement suffisant. Mon petit outil ne dépasse pas quelques centaines d’appels par jour.

100 000/jour
Quota gratuit
Largement suffisant pour un projet perso
5 minutes
Temps de déploiement
De la création à la mise en ligne
50-100 ¥/mois
Économie
Par rapport à un serveur dédié

Cloudflare dispose de plus de 200 centres de données dans le monde ; votre code s’y déploie automatiquement. L’utilisateur est routé vers le nœud le plus proche — latence faible. Contrairement à un serveur fixe dans une région, les autres zones restent lentes.

Autre point important : pas de cold start notable. Les fonctions Serverless (AWS Lambda) peuvent mettre plusieurs secondes après une longue inactivité. Workers répond en millisecondes, proche d’un serveur classique.

Déploiement extrêmement simple

Ma première fois avec Workers : de l’inscription au déploiement, 5 minutes. Sans exagération.

Pas de serveur à configurer, pas de Node.js ni Nginx à installer, pas de certificat SSL à demander (HTTPS automatique). Il suffit de :

  1. Écrire le code (un fichier JS, quelques dizaines de lignes)
  2. Lancer : wrangler publish
  3. C’est tout

Cloudflare fournit un domaine du type your-worker.your-subdomain.workers.dev, utilisable directement. Domaine personnalisé possible via la console, sans config supplémentaire.

Comparez au schéma classique : acheter un serveur → configurer l’environnement → coder → Nginx → certificat → déployer → tester… rien que la liste fatigue.

Résolution naturelle du CORS

Les appels frontend vers des API tierces déclenchent souvent des erreurs CORS, par exemple : Access to fetch at 'xxx' from origin 'yyy' has been blocked by CORS policy.

Le navigateur bloque les requêtes cross-origin. La solution habituelle : que le fournisseur API ajoute les en-têtes CORS — impossible si vous ne contrôlez pas son serveur.

Avec un proxy Workers :

  • Le frontend appelle votre Worker (ex. https://api.yourdomain.com)
  • Le Worker appelle l’API tierce
  • Le Worker renvoie la réponse avec les en-têtes CORS

Pour le navigateur, c’est same-origin. Pour l’API tierce, l’appel vient du serveur Workers — pas de CORS non plus.

J’avais des erreurs CORS avec l’API Amap ; deux lignes de code dans le proxy ont suffi.

Mise en pratique : votre premier proxy API

Voici comment procéder, pas à pas. Exemple avec l’API OpenAI ; la méthode est similaire pour d’autres API.

Étape 1 : préparation de l’environnement

1. Créer un compte Cloudflare

Inscrivez-vous sur cloudflare.com — le plan gratuit suffit. Vérification par e-mail, c’est rapide.

2. Installer Wrangler CLI

Wrangler est l’outil en ligne de commande officiel pour créer et déployer des Workers.

npm install -g wrangler

Sans Node.js, installez-le depuis nodejs.org.

3. Connexion et autorisation

wrangler login

La commande ouvre le navigateur pour autoriser l’accès. Ensuite, Wrangler gère vos Workers.

Étape 2 : créer le projet Worker

wrangler init openai-proxy

Quelques questions :

  • « Would you like to use TypeScript? » → No (sauf si vous maîtrisez TS)
  • « Would you like to create a new Worker? » → Yes
  • « Would you like to install dependencies? » → Yes

Structure générée :

openai-proxy/
├── src/
│   └── index.js       # Votre code ici
├── wrangler.toml      # Configuration
└── package.json

Étape 3 : écrire le code du proxy

Ouvrez src/index.js, supprimez le code par défaut et remplacez par :

export default {
  async fetch(request, env) {
    // Autoriser uniquement POST
    if (request.method !== 'POST') {
      return new Response('Method not allowed', { status: 405 });
    }
    // Lire la clé OpenAI depuis les variables d'environnement
    const apiKey = env.OPENAI_API_KEY;
    if (!apiKey) {
      return new Response('API Key not configured', { status: 500 });
    }
    try {
      // Corps de la requête envoyée par le frontend
      const body = await request.json();
      // Appel à l'API OpenAI
      const response = await fetch('https://api.openai.com/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${apiKey}`,  // Clé côté serveur
        },
        body: JSON.stringify(body),
      });
      // Données de réponse
      const data = await response.json();
      // Réponse au frontend avec en-têtes CORS
      return new Response(JSON.stringify(data), {
        status: response.status,
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',  // Tous les domaines autorisés
          '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' },
      });
    }
  },
};

En résumé :

  1. Recevoir la requête POST du frontend
  2. Lire la vraie clé API depuis les variables d’environnement (invisible côté client)
  3. Appeler l’API OpenAI avec cette clé
  4. Renvoyer la réponse avec les en-têtes CORS

Étape 4 : configurer les Secrets (stockage de la clé API)

Étape cruciale : ne jamais mettre la clé dans le code. Utilisez les Secrets Cloudflare.

wrangler secret put OPENAI_API_KEY

Collez votre clé OpenAI à l’invite. Elle est chiffrée côté Cloudflare ; même la console n’affiche pas le texte clair. Le code y accède via env.OPENAI_API_KEY.

Développement local ?

Créez un fichier .dev.vars à la racine :

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx

Uniquement pour le dev local — ne jamais committer sur Git. Ajoutez à .gitignore :

.dev.vars

Étape 5 : test local

Dans le dossier du projet :

wrangler dev

Serveur local sur http://localhost:8787. Testez avec Postman ou depuis le 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));

Une réponse OpenAI normale confirme que le proxy fonctionne.

Étape 6 : déploiement en production

Après les tests :

wrangler publish

Quelques secondes suffisent. Cloudflare fournit une URL du type :

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

Remplacez l’URL API dans votre frontend — la clé API ne sera jamais exposée.

Domaine personnalisé : dans la console Cloudflare, Workers → votre Worker → Settings → Triggers → Add Custom Domain, saisissez votre domaine (ex. api.yourdomain.com) et configurez le DNS.

Techniques avancées et bonnes pratiques

Le code ci-dessus fonctionne, mais quelques optimisations sont possibles.

Éviter l’abus de votre proxy

Votre Worker est public : quiconque connaît l’URL peut l’appeler. Un usage malveillant peut épuiser le quota gratuit, voire générer des frais.

Validation par token simple

export default {
  async fetch(request, env) {
    // Valider le token dans l'en-tête
    const token = request.headers.get('X-API-Token');
    if (token !== env.MY_SECRET_TOKEN) {
      return new Response('Unauthorized', { status: 401 });
    }
    // ... logique proxy suivante
  },
};

Puis wrangler secret put MY_SECRET_TOKEN. Le frontend envoie le token :

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

Ce token reste visible côté client, mais ajoute une barrière. Vous pouvez le faire tourner ou en attribuer un par utilisateur.

Liste blanche d’origines

Si l’app ne tourne que sur certains domaines :

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

Supporter plusieurs API

Pour plusieurs API, distinguez par chemin :

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    // Router selon le chemin
    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) {
  // Logique proxy OpenAI
}
async function proxyMaps(request, env) {
  // Logique proxy API cartes
}

Un seul Worker pour plusieurs API.

Gérer les requêtes OPTIONS (CORS complet)

Le code précédent ne gère que POST. Avant une requête cross-origin, le navigateur envoie souvent un OPTIONS (preflight). Gestion complète :

export default {
  async fetch(request, env) {
    // Requête preflight CORS
    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',
        },
      });
    }
    // ... traitement normal des requêtes
  },
};

Surveillance et débogage

La console Cloudflare affiche :

  • Nombre de requêtes
  • Taux d’erreur
  • Temps de réponse

Logs en temps réel :

wrangler tail

Les console.log() du code apparaissent aussi.

Questions fréquentes

Quota gratuit épuisé ?

100 000 requêtes par jour suffisent largement pour un projet perso. Le mien n’a jamais dépassé le quota en plusieurs mois.

Si ce n’est pas assez, le plan payant coûte 5 dollars pour 10 millions de requêtes — bien moins qu’un serveur dédié.

Workers est-il stable ?

Cloudflare est l’un des plus grands CDN au monde. En six mois d’usage, aucune indisponibilité. SLA officiel 99,99 % — plus fiable qu’un serveur maison.

Domaine personnalisé possible ?

Oui : liez le domaine dans la console, configurez le DNS — 5 minutes, HTTPS automatique.

Vitesse depuis la Chine ?

Cloudflare a des nœuds en Chine ; en général 100–300 ms, plus rapide qu’un appel direct vers l’étranger. Moins optimisé qu’un service domestic dédié ; pour une latence extrême, un Serverless local (Alibaba Function Compute) — mais config plus lourde.

Autres langages que JavaScript ?

Workers supporte surtout JavaScript et TypeScript. WebAssembly est possible, mais plus complexe. Pour un proxy API, JavaScript suffit.

Est-ce vraiment sécurisé ?

Oui, tant que vous ne renvoyez pas la clé API au frontend. Les Secrets sont chiffrés. Ajoutez tout de même un contrôle d’accès (token, liste blanche) pour limiter les abus.

Conclusion

La fuite de clé API m’a longtemps posé problème : accepter le risque ou payer un serveur.

Cloudflare Workers change la donne : 5 minutes de déploiement, gratuit, clé sécurisée, CORS réglé — presque la solution idéale pour un projet perso.

Si votre projet appelle des API tierces, essayez cette méthode. Suivez les étapes ci-dessus ; une demi-heure suffit.

Le code est prêt à copier-coller et adapter. Documentation Cloudflare ou commentaires sous l’article si besoin.

Dernier rappel : après déploiement, limitez l’accès — token ou restriction de domaine d’origine, simple et efficace.

Inscrivez-vous sur Cloudflare et testez !

Déployer un proxy API Cloudflare Workers pour protéger vos clés

Du risque des clés API côté frontend au déploiement Workers en 5 minutes, avec code et bonnes pratiques de sécurité

⏱️ Estimated time: 5 min

  1. 1

    Step 1: Comprendre les risques des clés API et les limites des solutions classiques

    Risques côté frontend :
    • Le code est transparent ; après le build, les variables d'environnement sont dans le JS
    • L'onglet Network expose requêtes, en-têtes et clé API
    • Obfuscation ou minification ne masquent pas la clé envoyée en requête

    Coût d'un vol :
    • Des outils scannent GitHub à la recherche de clés exposées
    • Usage frauduleux ou revente ; facturation OpenAI au token — centaines de yuans en une nuit
    • Exemple : page de chat IA, facture mensuelle > 2 000 USD après abus

    Limites des solutions classiques :
    • Coût : serveur minimal 50-100 ¥/mois
    • Complexité : Node.js, Nginx, SSL, CORS — une demi-journée
    • Maintenance : mises à jour, surveillance, redémarrages
  2. 2

    Step 2: Comprendre les avantages de Cloudflare Workers

    Gratuit et performant :
    • 100 000 requêtes gratuites par jour
    • Largement suffisant pour un projet perso
    • 200+ nœuds mondiaux, latence faible (100-300 ms en général)

    Sécurité de la clé :
    • Stockée côté serveur dans les variables d'environnement
    • Secrets chiffrés, invisible même dans la console
    • Le frontend n'y accède jamais

    Autres avantages :
    • Résolution CORS automatique
    • Déploiement en 5 minutes vs serveur + SSL + CORS
  3. 3

    Step 3: Déploiement en 5 minutes : Wrangler et création du Worker

    Étape 1 : installer Wrangler CLI
    • Terminal : npm install -g wrangler
    • Vérifier : wrangler --version

    Étape 2 : connexion Cloudflare
    • wrangler login — autorisation dans le navigateur
    • Message « Successfully logged in » attendu

    Étape 3 : créer le projet
    • mkdir api-proxy && cd api-proxy && wrangler init
    • Réponses par défaut ou TypeScript selon préférence
    • Fichiers : wrangler.toml, src/index.ts, package.json

    Étape 4 : stocker la clé API
    • wrangler secret put OPENAI_API_KEY
    • La clé reste côté serveur, inaccessible au frontend
  4. 4

    Step 4: Implémenter le code du proxy API

    Flux : recevoir la requête frontend → lire la clé depuis env → transférer vers l'API cible → ajouter la clé dans les en-têtes → renvoyer la réponse avec CORS. Support GET/POST et autres méthodes HTTP.
  5. 5

    Step 5: Déployer et appeler depuis le frontend

    Déploiement : wrangler deploy — URL du type your-worker-name.your-subdomain.workers.dev. Frontend : remplacer l'appel direct à l'API par l'URL Worker. Surveillance : console Cloudflare (requêtes, erreurs, latence) ou wrangler tail pour les logs.
  6. 6

    Step 6: Bonnes pratiques de sécurité et FAQ

    Bonnes pratiques : clé dans env/secrets, pas en dur ; limitation de débit ; validation de l'origine ; logs wrangler tail ; rotation de clé si anomalie. FAQ : quota 100k/jour suffisant ; plan payant 5 USD/10M requêtes ; SLA 99,99 % ; domaine personnalisé en 5 min ; latence Chine ~100-300 ms ; sécurité si la clé n'est jamais renvoyée au client.

FAQ

Pourquoi une clé API côté frontend n'est-elle pas sûre ? Pourquoi le vol entraîne-t-il des frais ?
Code frontend transparent :
• .env ou import.meta.env de Vite : après build, tout est dans le JS
• F12 → Network : requêtes, en-têtes, corps, paramètres — tout visible
• Obfuscation ne change pas le fait que la vraie clé part en requête
• Chiffrement côté client : le code de déchiffrement est aussi visible
• Le frontend tourne chez l'utilisateur — pas de contournement

Coût du vol :
• Scanners GitHub cherchent les clés exposées
• Abus ou revente ; OpenAI facture au token — centaines de yuans par nuit
• Exemple : chat IA, facture > 2 000 USD/mois
• Google Maps, météo, traduction — même risque si facturation à l'usage
Quels avantages offre Cloudflare Workers ? Pourquoi le choisir ?
Gratuit et performant :
• 100 000 requêtes/jour gratuites
• Suffisant pour la plupart des projets perso
• 200+ nœuds, routage vers le plus proche, ~100-300 ms

Clé côté serveur :
• Secrets chiffrés, invisible dans la console
• Frontend sans accès à la clé
• CORS géré par le Worker

Déploiement rapide :
• ~5 minutes vs serveur + SSL + CORS

Limites des alternatives :
• Coût serveur 50-100 ¥/mois
• Config Node.js, Nginx, SSL, CORS
• Maintenance continue
Comment déployer un proxy API avec Cloudflare Workers ?
Déploiement en 5 minutes :

1) npm install -g wrangler — vérifier wrangler --version
2) wrangler login — autorisation navigateur
3) mkdir api-proxy, cd, wrangler init
4) wrangler secret put OPENAI_API_KEY — saisir la clé

Code : recevoir requête → lire clé env → transférer → en-têtes Authorization → réponse + CORS

Déploiement : wrangler deploy → URL workers.dev

Frontend : appeler l'URL Worker au lieu de l'API directe — clé jamais exposée.
Le quota gratuit Workers suffit-il ? Que faire s'il est épuisé ?
Quota :
• 100 000 requêtes/jour gratuites
• Largement suffisant pour un projet perso (quelques centaines/jour typiquement)
• Mon usage : jamais dépassé en plusieurs mois
• Plan payant : 5 USD/mois pour 10 millions de requêtes

Surveillance :
• Console : requêtes, erreurs, latence
• wrangler tail pour logs et console.log
Workers est-il stable ? Domaine personnalisé ? Vitesse depuis la Chine ?
Stabilité :
• Infrastructure Cloudflare très fiable
• SLA 99,99 %
• Moins de pannes qu'un serveur auto-hébergé

Domaine personnalisé :
• Liaison + DNS en ~5 minutes, HTTPS automatique

Chine :
• Nœuds présents, ~100-300 ms, mieux qu'appel direct à l'étranger
• Moins optimisé qu'un service domestic ; Serverless local possible si latence critique
Est-ce vraiment sécurisé ? Quelles bonnes pratiques ?
Sécurité :
• Sûr si la clé API n'est jamais renvoyée au frontend
• Secrets chiffrés côté Cloudflare
• Contrôle d'accès indispensable contre l'abus

Bonnes pratiques :
1) wrangler secret put — jamais de clé en dur dans le code
2) Rate limiting Cloudflare si besoin
3) Validation Referer/CORS — domaines autorisés uniquement
4) Logs wrangler tail
5) Rotation de clé en cas d'anomalie

Token ou liste blanche d'origines : simple et efficace après déploiement.

10 min de lecture · Publié le: 1 déc. 2025 · Mis à jour le: 27 juil. 2026

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog