フロントに API Key を置いて不正利用された?Workers プロキシで 5 分、キーを守り毎日 10 万リクエスト無料
ChatGPT API を叩く小さなツールを作り、API Key をフロントのコードに直書きした。翌日、口座から 300 元ほどが不正利用で引き落とされていた——一晩で数千回呼ばれていた。環境変数でもダメ。Vite や Webpack の環境変数は最終的に JS にバンドルされ、ユーザーが Network パネルを開けばリクエスト全体が見えてしまう。
従来はバックエンドサーバーでプロキシを立てる方法が一般的だが、サーバー代がかかり、環境構築や SSL 証明書、CORS 設定も必要。Cloudflare Workers なら 5 分で API プロキシをデプロイでき、API Key はサーバー側の環境変数に置けるのでフロントは一切触れない。完全無料で、毎日 10 万リクエストまで使える。本記事では構築手順を解説する。
なぜ API Key をフロントに置いてはいけないのか
フロントのコードは完全に透明
.env や Vite の import.meta.env を使えば安全、と思っている人が多い。実際は開発時の便利ツールにすぎず、ビルド後はすべての環境変数が JS にハードコードされる。
試してみてほしい。本番のフロントを開き、F12 で開発者ツール → Network パネル → ページをリロード。API リクエストのヘッダー、ボディ、URL パラメータがすべて見える。
難読化や圧縮をしても、読みにくくするだけ。API 呼び出しには本物の Key を送る必要があり、それは隠せない。暗号化を考える人もいるが、復号コードもフロントにある以上、ユーザーは同じことができる。
要するに、フロントはユーザーのブラウザ上で動く。あなたができることは、ユーザーにもできる。これは構造的に解決できない。
不正利用の代償は大きい
「誰がわざわざ私のコードから API Key を抜くの?」と思っていた。実際には、それ専門の人がいる。
GitHub には、コード内の API Key を自動スキャンするツールがある。見つけた Key で API を叩き、自分で使うか、他人に売る。OpenAI API はトークン課金なので、一晩で数百元の請求は珍しくない。深刻なケースでは数千元に達することもある。
開発者フォーラムでは、AI チャットページに Key をフロントに置いた人が、抜かれた後に狂ったように呼び出され、月の請求が 2,000 ドル超えになった、という話もあった。異議申し立ては通ったが、かなり面倒だったそうだ。
OpenAI だけではない。Google Maps API、天気 API、翻訳 API など、従量課金の API はすべて同じリスクがある。
従来の解決策の問題点
リスクがわかると、ネット上の定番回答は「バックエンドサーバーでプロキシを立てる」になる。
シンプルに聞こえるが、実際は次のとおり。
- コスト:最安の VPS(Alibaba Cloud や Tencent Cloud の軽量サーバー)でも月 50〜100 元。個人プロジェクトには重い。
- 設定の複雑さ:Node.js などの実行環境、Nginx リバースプロキシ、SSL 証明書、HTTPS、CORS 設定……理解するだけで半日。
- 運用コスト:更新、監視、ダウン時の再起動。小さなプロジェクトには負担が大きい。
国内クラウドの Serverless(Alibaba Cloud 関数計算、Tencent Cloud SCFなど)は安くなるが、設定はさらに複雑で、コールドスタートも遅く、ドキュメントも使いにくい。何度か試したが、うまくいかなかった。
API ゲートウェイは企業向けで、個人開発者にはハードルが高い。
Cloudflare Workers ソリューションのメリット
完全無料で高性能
Cloudflare Workers の無料枠は毎日 10 万リクエスト。個人プロジェクトなら十分。私の小さなツールは 1 日数百回程度で、無料枠に余裕がある。
Cloudflare は世界 200 以上のデータセンターを持ち、コードは自動的に各拠点に配信される。ユーザーは最寄りの拠点にルーティングされ、応答が速い。従来サーバーのように、購入リージョン以外は遅くなりにくい。
Workers にはコールドスタート問題がほぼない。AWS Lambda などの Serverless は長時間アイドル後、次の呼び出しで数秒かかることがある。Workers はミリ秒級で、従来サーバーに近い体感になる。
デプロイが驚くほど簡単
初めて Workers を使ったとき、登録からデプロイまで本当に 5 分だった。
サーバー環境の構築、Node.js や Nginx のインストール、SSL 証明書の取得は不要。Workers は HTTPS も自動。やることは次の 3 つ。
- コードを書く(JS ファイル 1 つ、数十行)
wrangler publishを実行- 完了
デプロイ後、your-worker.your-subdomain.workers.dev のような URL がもらえる。独自ドメインもコンソールからバインドするだけで、追加設定はほぼ不要。
従来フロー:サーバー購入 → 環境構築 → コード → Nginx → 証明書 → デプロイ → テスト……見るだけで疲れる。
CORS 問題を自然に解決
フロントから第三者 API を呼ぶと、Access to fetch at 'xxx' from origin 'yyy' has been blocked by CORS policy のような CORS エラーが出がち。
ブラウザのセキュリティ制限で、異なるオリジン間のリクエストがブロックされる。API 提供側の CORS 設定を変えられないケースが多い。
Workers プロキシなら次のように解決できる。
- フロントは自分の Worker URL(例:
https://api.yourdomain.com)を呼ぶ - Worker が第三者 API を呼ぶ
- Worker がレスポンスに CORS ヘッダーを付けて返す
ブラウザから見れば同一オリジン。第三者 API から見れば Worker サーバーからの呼び出し。どちらも CORS 問題が起きない。
地図 API を呼んでいたとき、ずっと CORS エラーが出ていたが、Workers プロキシにしたら 2 行追加で解決した。
実践:最初の API プロキシを構築する
メリットを説明したので、手順に入る。OpenAI API のプロキシを例にする。他 API もほぼ同じ。
ステップ 1:環境準備
1. Cloudflare アカウント登録
cloudflare.com で無料登録。メール認証だけで OK。
2. Wrangler CLI のインストール
Wrangler は Cloudflare 公式の CLI ツール。
npm install -g wrangler
Node.js がなければ nodejs.org からインストール。
3. ログイン・認可
wrangler login
ブラウザが開くので許可する。以降、CLI から Workers を管理できる。
ステップ 2:Worker プロジェクト作成
wrangler init openai-proxy
質問が出たら次のように答える。
- “Would you like to use TypeScript?” → No(TS に慣れていなければ)
- “Would you like to create a new Worker?” → Yes
- “Would you like to install dependencies?” → Yes
完了すると、おおよそ次の構成になる。
openai-proxy/
├── src/
│ └── index.js # コードはここ
├── wrangler.toml # 設定ファイル
└── package.json
ステップ 3:プロキシコードを書く
src/index.js を開き、デフォルトコードを削除して次を貼る。
export default {
async fetch(request, env) {
// POST のみ許可
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
// 環境変数から OpenAI API Key を読み取り
const apiKey = env.OPENAI_API_KEY;
if (!apiKey) {
return new Response('API Key not configured', { status: 500 });
}
try {
// フロントからのリクエストボディを取得
const body = await request.json();
// 本物の OpenAI API を呼び出し
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`, // サーバー側の Key を使用
},
body: JSON.stringify(body),
});
// レスポンスデータを取得
const data = await response.json();
// フロントへ返却し、CORS ヘッダーを追加
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' },
});
}
},
};
処理の流れはシンプル。
- フロントから POST を受け取る
- 環境変数から本物の API Key を読む(フロントは見えない)
- その Key で OpenAI API を呼ぶ
- 結果を CORS ヘッダー付きで返す
ステップ 4:Secrets 設定(API Key の保存)
ここが最重要。API Key はコードに書かず、Cloudflare Secrets で暗号化保存する。
wrangler secret put OPENAI_API_KEY
Key の値を貼り付けて Enter。Cloudflare 上に暗号化保存され、コンソールでも平文は見えない。コードでは env.OPENAI_API_KEY で参照できる。
ローカル開発は?
プロジェクトルートに .dev.vars を作成。
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
ローカル開発専用。Git にコミットしない。.gitignore に追加。
.dev.vars
ステップ 5:ローカルテスト
プロジェクトディレクトリで実行。
wrangler dev
http://localhost:8787 でローカルサーバーが起動。Postman かフロントコードでテスト。
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));
OpenAI のレスポンスが返れば、プロキシは正常。
ステップ 6:本番デプロイ
問題なければ 1 コマンドでデプロイ。
wrangler publish
数秒で完了。URL は例えば次の形式。
https://openai-proxy.your-subdomain.workers.dev
フロントの API 先をこれに差し替えれば完了。API Key はフロントに一切出ない。
独自ドメインを使う場合、Cloudflare コンソールの Workers → 対象 Worker → Settings → Triggers → Add Custom Domain で api.yourdomain.com などを入力し、DNS を設定する。
応用テクニックとベストプラクティス
上記コードで動くが、さらに改善できる点がある。
プロキシの悪用を防ぐ
Worker URL を知っている人なら誰でも呼べる。悪意ある大量呼び出しで無料枠を使い切ったり、有料枠に入ったりする恐れがある。
シンプルな Token 検証
export default {
async fetch(request, env) {
// リクエストヘッダーの token を検証
const token = request.headers.get('X-API-Token');
if (token !== env.MY_SECRET_TOKEN) {
return new Response('Unauthorized', { status: 401 });
}
// ... 以降のプロキシ処理
},
};
wrangler secret put MY_SECRET_TOKEN で秘密トークンを設定。フロント呼び出し時に付与。
fetch('https://your-worker.workers.dev', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Token': 'your-secret-token', // フロント環境変数に置いても可
},
body: JSON.stringify(data),
});
フロントからは見えるが、ハードルは 1 段上がる。定期的に token をローテーションしたり、ユーザーごとに分けたりできる。
IP / オリジン制限
特定ドメインだけ許可する例。
const allowedOrigins = ['https://yourdomain.com', 'http://localhost:3000'];
const origin = request.headers.get('Origin');
if (!allowedOrigins.includes(origin)) {
return new Response('Forbidden', { status: 403 });
}
複数 API に対応
パスで振り分ける。
export default {
async fetch(request, env) {
const url = new URL(request.url);
// パスに応じて API を振り分け
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 プロキシ処理
}
async function proxyMaps(request, env) {
// 地図 API プロキシ処理
}
1 つの Worker で複数 API を扱える。
OPTIONS リクエスト(完全な CORS 対応)
上記コードは POST のみ。ブラウザは本リクエスト前に OPTIONS プリフライトを送る。完全対応は次のように。
export default {
async fetch(request, env) {
// 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',
},
});
}
// ... 通常のリクエスト処理
},
};
監視とデバッグ
Cloudflare コンソールで次を確認できる。
- リクエスト数
- エラー率
- 応答時間
リアルタイムログは wrangler tail。
wrangler tail
すべてのリクエストログが流れる。console.log() の出力も表示される。
よくある質問
無料枠を使い切ったら?
毎日 10 万リクエストは個人プロジェクトなら十分。私のプロジェクトは数ヶ月、一度も超えていない。
本当に足りなければ、有料プランは月 5 ドルで 1,000 万リクエスト。自前サーバーと比べれば安い。
Workers は安定する?突然落ちない?
Cloudflare は世界最大級の CDN 事業者の一つで、インフラは非常に信頼性が高い。半年以上使っているが、サービス停止は経験していない。
公式 SLA は 99.99%。自前サーバーより障害リスクは低い。
独自ドメインは使える?
可能。コンソールでカスタムドメインをバインドし、DNS を設定するだけ。5 分程度、証明書設定は不要(自動 HTTPS)。
国内からのアクセス速度は?
Cloudflare は国内にも拠点があり、速度は悪くない。テストでは応答 100〜300ms 程度で、海外 API を直接叩くより速い。
国内最適化サービスほどではない。速度が最優先なら Alibaba Cloud 関数計算などもあるが、設定は複雑。
JavaScript 以外は使える?
主に JavaScript / TypeScript。他言語は WebAssembly コンパイルも可能だが、ハードルは高い。
API プロキシ程度なら JavaScript で十分。
本当に安全?
レスポンスに API Key を含めなければ安全。Secrets は暗号化保存で、コンソールでも平文は見えない。
ただしアクセス制御は必須。token 検証やオリジン制限を併用しよう。
まとめ
API Key 漏えい問題に、長い間悩んでいた。リスクを受け入れるか、サーバー代を払うか、二択だと思っていた。
Cloudflare Workers を知って、こんなに簡単だと気づいた。5 分デプロイ、完全無料、Key の安全保管、CORS 解決——個人プロジェクトにはほぼ理想的。
第三者 API を呼ぶプロジェクトなら、ぜひ試してほしい。手順どおりなら 30 分あれば十分。
コードはそのままコピーして改変できる。困ったら Cloudflare 公式ドキュメント を参照。
最後に:デプロイ後はアクセス制御を忘れずに。token 検証やオリジン制限は簡単で効果的。
今すぐ Cloudflare アカウントを作って試してみよう。
Cloudflare Workers で API プロキシを構築しキーを保護する完全手順
API Key のセキュリティリスクを理解し、5 分で Workers をデプロイ。コード実装と安全なベストプラクティスを含む
⏱️ 目安時間: 5 分
- 1
ステップ1: API Key のリスクと従来ソリューションの問題を理解する
フロントの API Key 問題:
• フロントコードは完全に透明。環境変数もビルド後は JS にハードコードされる
• Network パネルでリクエスト全体(API Key 含む)が見える
• 難読化・圧縮しても、本物の Key を送る必要があり隠せない
• 暗号化しても復号コードがフロントにあれば意味がない
不正利用の代償:
• GitHub には API Key を自動スキャンするツールがある
• 見つけた Key で API を叩き、タダ乗りや転売に使われる
• OpenAI API はトークン課金。一晩で数百元の請求は珍しくない
• AI チャットページに Key を置いた例では、月 2,000 ドル超の請求に
従来ソリューションの問題:
• コスト:最安 VPS でも月 50〜100 元。個人プロジェクトには重い
• 設定:Node.js、Nginx、SSL、CORS など、理解だけで半日
• 運用:更新・監視・再起動。小プロジェクトには負担大 - 2
ステップ2: Cloudflare Workers ソリューションのメリットを把握する
完全無料で高性能:
• 無料枠は毎日 10 万リクエスト
• 個人プロジェクトには十分。1 日数百回なら余裕
• 世界 200 以上の拠点。最寄りルーティングで 100〜300ms 程度
API Key の安全:
• サーバー側環境変数に保管
• Secrets は暗号化。コンソールでも平文不可
• フロントは一切触れない
その他の強み:
• CORS を Worker 側で処理
• 5 分デプロイ(自前サーバーより圧倒的に簡単) - 3
ステップ3: 5 分デプロイ:Wrangler インストールと Worker 作成
ステップ 1:Wrangler CLI インストール
• ターミナルで npm install -g wrangler
• wrangler --version で確認
ステップ 2:Cloudflare ログイン
• wrangler login を実行
• ブラウザで許可 → Successfully logged in
ステップ 3:Worker プロジェクト作成
• mkdir api-proxy && cd api-proxy
• wrangler init
• TypeScript は好みで Yes/No
• wrangler.toml、src/index.ts、package.json が生成される
ステップ 4:環境変数で API Key 保存
• wrangler secret put OPENAI_API_KEY
• Key を入力。サーバー側に安全保管、フロントは触れない - 4
ステップ4: コアコードで API プロキシを実装
処理:フロントリクエスト受信 → 環境変数から API Key 読取 → ターゲット API へ転送 → ヘッダーに Key 付与 → レスポンス返却。GET/POST など HTTP メソッドに対応可能。 - 5
ステップ5: デプロイとフロントからの呼び出し
wrangler deploy(または wrangler publish)でデプロイ。your-worker-name.your-subdomain.workers.dev が発行される。フロントは直接 API を叩く代わりに Worker URL を呼ぶ。API Key はサーバー側のみ。Cloudflare コンソールでリクエスト数・エラー率・応答時間を確認。wrangler tail でリアルタイムログ。 - 6
ステップ6: 安全なベストプラクティスと FAQ
1) Key は環境変数、ハードコード禁止(wrangler secret put)2) Rate Limiting で悪用防止 3) Referer/CORS でオリジン制限 4) wrangler tail で異常監視 5) 異常時は Key をローテーション。無料枠不足なら月 5 ドルで 1,000 万リクエスト。SLA 99.99%。独自ドメインは 5 分で HTTPS 自動。国内応答 100〜300ms 程度。
FAQ
なぜフロントの API Key は安全でないのか?なぜ不正利用される?
• .env や Vite の import.meta.env も、ビルド後は JS にハードコードされる
• F12 → Network でリクエスト全体が見える
• 難読化しても本物の Key は送る必要があり隠せない
• 暗号化しても復号コードがフロントにある
• ブラウザ上で動く以上、ユーザーにも同じことができる
不正利用の代償:
• GitHub 上の API Key 自動スキャン
• タダ乗りや転売
• OpenAI はトークン課金。一晩数百元は珍しくない
• 月 2,000 ドル超の事例も
• Google Maps、天気、翻訳 API など従量課金はすべて同リスク
Cloudflare Workers ソリューションのメリットは?なぜ選ぶ?
• 毎日 10 万リクエスト無料
• 個人プロジェクトには十分
• 200 以上の拠点、100〜300ms 程度
API Key はサーバー側で安全:
• Secrets 暗号化、フロント非接触
• CORS も Worker 側で処理
5 分デプロイ:
• 自前サーバーより圧倒的に簡単
従来ソリューションの問題:
• 月 50〜100 元のサーバー代
• Node.js、Nginx、SSL、CORS の設定負担
• 運用・監視の手間
Cloudflare Workers で API プロキシを構築する手順は?
ステップ 1:npm install -g wrangler、wrangler --version で確認
ステップ 2:wrangler login でブラウザ認可
ステップ 3:mkdir api-proxy、cd api-proxy、wrangler init
ステップ 4:wrangler secret put OPENAI_API_KEY で Key をサーバー側保存
コアコード:
• リクエスト受信 → 環境変数から Key → ターゲット API 転送 → CORS 付きで返却
デプロイ:
• wrangler deploy / wrangler publish
• your-worker-name.your-subdomain.workers.dev が発行
フロントは Worker URL を呼び、Key はサーバー側のみ
Workers の無料枠は足りる?使い切ったら?
• 毎日 10 万リクエスト
• 個人プロジェクトには十分。数ヶ月使っても超えたことがない
• 足りなければ月 5 ドルで 1,000 万リクエスト
• 自前サーバーより安い
監視:
• コンソールでリクエスト数・エラー率・応答時間
• wrangler tail でリアルタイムログ
Workers は安定?独自ドメインは?国内速度は?
• 世界最大級 CDN のインフラ
• 半年以上、停止を経験していない
• SLA 99.99%
独自ドメイン:
• コンソールでバインド、DNS 設定のみ
• 5 分程度、HTTPS 自動
国内速度:
• 国内拠点あり、100〜300ms 程度
• 海外 API 直接より速い
• 国内最適化ほどではない。速度最優先なら Alibaba Cloud 関数計算など(設定は複雑)
本当に安全?セキュリティのベストプラクティスは?
• レスポンスに Key を含めなければ安全
• Secrets は暗号化、コンソールでも平文不可
• アクセス制御は必須
ベストプラクティス:
1) 環境変数に Key、ハードコード禁止(wrangler secret put)
2) Rate Limiting で悪用防止
3) Referer/CORS でオリジン制限
4) wrangler tail で異常監視
5) 異常時は Key ローテーション
token 検証やオリジン制限は簡単で効果的。デプロイ後は必ず設定しよう
5分で読めます · 公開日: 2025年12月1日 · 更新日: 2026年6月8日
Cloudflare フルスタック実践
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Workers + KV で自前の短縮 URL サービスを構築:入門から実践まで
サードパーティの短縮 URL サービスが突然終了して数百のリンクが無効に?Cloudflare Workers + KV でカスタム短縮コードやアクセス統計に対応した自前サービスを構築する方法を解説。デプロイは簡単、グローバル高速、基本無料。
第 15 / 23 記事
次の記事
Workers の無料枠が足りない?7 つの最適化で 1 日 10 万リクエストを 1 ヶ月持たせる
Cloudflare Workers の無料枠(1 日 10 万リクエスト)が足りない?課金ルールを深掘りし、実戦で使える 7 つの最適化テクニックを公開。実例:画像ホスティングの日次リクエストを 12 万から 3 万に削減、キャッシュヒット率 80% 向上、年間 60 ドル節約。
第 17 / 23 記事
関連記事
Cloudflare無料版の制限2026:Free、Pro、Business料金比較
Cloudflare無料版の制限2026:Free、Pro、Business料金比較
Cloudflare Pages で静的ブログをデプロイする完全ガイド:5 大フレームワークの設定で落とし穴を避ける
Cloudflare Pages で静的ブログをデプロイする完全ガイド:5 大フレームワークの設定で落とし穴を避ける
Cloudflare Pages でフロントエンドをデプロイする完全ガイド:React/Vue/Next.js の設定とエラー対処
コメント
GitHubアカウントでログインしてコメントできます