Day 4・非同期とfetchでAPIを叩く
環境変数とAPIキー(秘密はフロントに置かない)
APIキーなどの秘密は環境変数で管理し、ブラウザに露出させない。
APIキーは「秘密」である
多くのAPIは、利用するときにAPIキー(合言葉のような文字列)を必要とします。このキーは、あなたのアカウントで課金される権利そのものです。もし他人に知られると、勝手に使われて高額な請求が来たり、データを盗まれたりします。つまりAPIキーはパスワードと同じ「秘密」で、コードに直接書いたり、外に見える場所に置いたりしてはいけません。
フロントエンドに秘密を置くと全員に見える
ブラウザで動くコード(フロントエンド)は、利用者が中身を自由にのぞけます。開発者ツールを開けば、埋め込まれた文字列はすべて見えます。APIキーをフロントに書くと、サイトを訪れた誰もがそのキーを読み取れてしまいます。
環境変数で秘密をコードの外に出す
秘密の値は、コードに直接書かずに環境変数として渡します。環境変数とは、プログラムの外側(実行環境)に用意しておく設定値のことです。Node.jsでは process.env から読み取ります。実際の値は .env という設定ファイルに書き、そのファイルはGitなどで共有しない(.gitignoreに入れる)のが基本です。
// .env ファイル(この中身は共有しない)
// API_KEY=sk-xxxxxxxxxxxxxxxx
// サーバー側のコードから読み取る
const apiKey = process.env.API_KEY;
if (!apiKey) {
// 設定漏れに早く気づけるようにチェックする
throw new Error("API_KEY が設定されていません");
}秘密を使う処理はサーバー側で行う
では、ブラウザからAPIキーが必要なAPIを呼びたいときはどうするか。答えは「ブラウザから直接呼ばない」です。自分のサーバー(Next.jsなら などのサーバー側の入口)にリクエストを送り、そのサーバーの中でAPIキーを使って本物のAPIを呼びます。キーはサーバーの中だけに存在し、ブラウザには渡りません。
ブラウザから直接呼ぶ
// フロントのコード(ブラウザで動く)
const res = await fetch("https://api.example.com/chat", {
headers: { Authorization: "Bearer " + apiKey },
});
// apiKey がブラウザに埋め込まれ、誰でも見える自分のサーバー経由で呼ぶ
// フロントは自分のサーバーだけを呼ぶ
const res = await fetch("/api/chat", { method: "POST" });
// キーはサーバー側の process.env にあり、ブラウザに出ないなぜサーバーを経由させるのか
秘密を使う処理を自分のサーバーの中に閉じ込めるためです。ブラウザには「自分のサーバーの入口」だけを見せ、本物のAPIキーはサーバーの環境変数から使う。こうすればキーが利用者に漏れません。AIプロダクトでAIのAPIを使うときも、この形が基本です。
AIにはこう聞く
「このAPIキーを使う処理を、フロントから直接呼ばずにサーバー側(APIルート)に移して、キーは環境変数から読むようにして」と頼むと、安全な構成に直してもらえます。生成後は「キーがフロントのコードに残っていないか」を必ず確認しましょう。
- APIキーはパスワードと同じ秘密。コードに直書きしない
- フロントに置くと利用者全員に見えてしまう
- 秘密は環境変数(process.env)で渡し、.envは共有しない
- 秘密を使う処理はサーバー側で行い、ブラウザからは自分のサーバー経由で呼ぶ
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
APIキーの扱いとして最も安全なものは?
フロントエンド(ブラウザで動くコード)にAPIキーを埋め込むと何が問題ですか?
APIキーをフロントに置かず、環境変数とサーバー経由で扱う理由を説明してください。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。