🔐

Next.jsの環境変数のセキュリティ

2025/02/17に公開

執筆者について

実務未経験&プログラム歴1年未満です。

記事本文

自信のブログ記事をNext.js(ver.14)+microCMSで構築していますが、途中のエラー対応の理解が浅く、場当たり的な対応をしていたこともあり、重要なセキュリティ問題があったことが分かりました。
https://www.masato-tech-blog.com/

環境変数に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にデプロイする際に別の問題が発生し、そちらに時間がかかり苦労しました。それについては別途記事にしたいと思います。

GitHubで編集を提案

Discussion