Next.jsの環境変数のセキュリティ
執筆者について
実務未経験&プログラム歴1年未満です。
記事本文
自信のブログ記事をNext.js(ver.14)+microCMSで構築していますが、途中のエラー対応の理解が浅く、場当たり的な対応をしていたこともあり、重要なセキュリティ問題があったことが分かりました。
環境変数にNEXT_PUBRICを付けていたため、開発者ツールからAPI_KEYを確認できる状態でした。
NEXT_PUBLIC_API_KEY=【API KEY】
【今回の教訓】
NEXT_PUBRICのプレフィックスを安易に使わない
■変更前
microCMSのクライアントライブラリを使って記事データを取得していました。
const client = createClient({
serviceDomain: 'your-service-domain',
apiKey: process.env.NEXT_PUBLIC_API_KEY,
});
この実装では、NEXT_PUBLICプレフィックスによって環境変数がクライアントサイドのJavaScriptに含まれてしまいます。これは、Next.jsの仕様でNEXT_PUBLICが付いた環境変数はビルド時にバンドルに含まれるためです。結果として、ブラウザの開発者ツールからAPI_KEYが確認できてしまう状態となっていました。
■変更後
この問題を解決するため、ファイルルーティングの構造を変更しました。具体的には、以下のようにAPI Routeを実装し、API経由でブログ記事を取得することで、クライアントサイドからAPI Keyが見えないようにしました
Next.jsではapiフォルダを配置することで、APIエンドポイントとして使用できます:
// app/api/route.ts
import { createClient } from 'microcms-js-sdk';
import { NextResponse } from 'next/server';
const client = createClient({
serviceDomain: 'your-service-domain',
apiKey: process.env.API_KEY, // NEXT_PUBLICプレフィックスを削除
});
export async function GET() {
const data = await client.get({
endpoint: 'blogs',
});
return NextResponse.json(data);
}
まとめ
API Routeを使用することで、クライアントサイドに露出させることなく、安全にmicroCMSの記事を取得できるようになりました。
たぶん初心者にありがちなミスと思いますが、付け焼刃でセキュリティキーを扱うのは危険が伴うので、十分な注意が必要ですね。
※この他にもクライアントサイドでcreateClient()を使用しているファイルをインポートする場合でも露出してしまうようです。今回であればFooter.tsxを'use client'に設定しており、そこからcreateClientを使っているファイルをインポートしてしまっていました。
大変だったのは今回のAPIルートを導入したことによってVercelにデプロイする際に別の問題が発生し、そちらに時間がかかり苦労しました。それについては別途記事にしたいと思います。
Discussion