カミナシ エンジニアブログ

株式会社カミナシのエンジニアが色々書くブログです

ただNext.jsを使う

カミナシエンジニアの osuzu です。

私は職能柄、Webフロントエンド技術の選定に関わる機会が多く、これまで React Server ComponentNext.js に関する発信なども過去にしていました。

そうした事情から2025年12月の ReactNext.jsのセキュリティ問題 に対し心痛めています。

私は現在もプロダクションでNext.jsを運用していますが、選定した事を後悔しているかというとそう単純な話でもありません。 そこであらためて、Next.jsをプロダクションで採用するポイント、何を意識した構成にしているか記載します。

今回の記事では以降、ReactはRSC(React Server Component)を含むものとし、Next.jsは記載のない限りApp Routerを指した話となります。

BFFとして使う

まず私はプロダクション運用するプロダクトに対して、フルスタックフレームワークやバックエンドを兼ねる形でNext.jsを採用する事はありません。必ずBFFとして使います。ここであらためてBFFとして使う事について整理します。

今回は主にSaaSのような、認証認可が必要かつ、マルチプロダクト展開や他SaaS連携などで複数のAPIに依存しやすい構成を例に説明します。

BFFの構成について

私が推奨する「Next.jsをBFFとして使う」構成は、物理的にも論理的にもバックエンドAPIと明確に分離された状態を指します。 具体的には、Next.jsはデータベースへの接続情報を一切持たず、ビジネスロジックも記述しません。あくまで「UIのためのデータ整形」「APIアグリゲーション」「API認可プロキシ」に徹します。

「ブラウザの延長」と捉え、機密情報を保持しない

Next.jsサーバー(Node.js/Edge Runtime)を「信頼できるサーバー(Trusted)」とは見なさず、「ブラウザが少し権限を持った延長線上の環境(Untrusted)」として扱います。 具体的には、「ブラウザのDevToolsで見えて困るロジックや変数は、Next.jsのサーバーサイドにも置かないという極端な意識で設計します。

そのため、DBのパスワードやAWSのシークレットキーを環境変数として渡すことはありません。これにより、万が一RSCの境界設定ミスでコードが流出したり、インジェクション攻撃を受けたとしても、攻撃者が手に入れられるのは「画面構築のためのロジック」だけであり、システム全体を掌握されるリスクを構造的に低減します。

BFFのインフラ権限を最小化し、トークンの検証責務をバックエンドAPIが持つこと

BFFが実行されるコンテナや関数自体の権限(IAM Role等)は最小限に絞ります。 例えばAWS上で運用する場合、Next.jsの実行ロールに対して dynamodb:FullAccess は与えずに、 dynamodb:GetItemdynamodb:PutItem など権限を最小限にします。

また、認証認可のフローにおいてもNext.jsはあくまでトークンの「運搬役」に徹します。例えばNext.js上でJWTを発行するといった構成は取りません。

カミナシが運用するプロダクトでは、バックエンドAPIはOAuthのクライアントでトークンイントロスペクションのリクエストするだけという構成を取っています。Next.jsはCookieからトークンを取り出しAPIへ転送するだけであり、バックエンドAPI側がそのトークンを検証するリクエスト結果を元に認可します。この徹底した責務の分離により、BFF層がセキュリティに対して権限やリスク集中することを防いでいます。

※ すべてのバックエンドAPIが同じセッションストアを共有する構成などでは、BFFでトークンを取得せずcookieをproxyするだけで扱って良いかもしれません。

[追記]

セッションストアへのアクセス権限を小さくする他にも以下のような対策があります。いずれもNext.jsなどBFF固有のものではありません。

  • コンテナをイミュータブルにする
  • CookieにHttpOnly, Secure, SameSite属性を設定する
  • Content Security Policyを設定する
  • サーバーのアウトバウンド通信を制限する
  • WAFを導入する

ただし、いずれも攻撃を難しくしたり被害範囲の縮小に役立つことはありますが、RCE(遠隔コード実行)が存在する場合にセッション乗っ取りリスクをゼロにするものではありません。

そこまでしてNext.jsを使う必要があるか

BFFは必要なのか

ここで議論になるのが、「そこまで制約を課すならSPA + APIで良いのではないか?」という点です。SaaSやtoBのプロダクトではSPA(Client Side Rendering)にすべきという意見もよく目にします。 例えば「SSRからSPAにしたとしてSaaSのようなプロダクトではボトルネックは移動しない」「静的なファイルとして配信した方がインフラコストが安い、またバンドルしたファイルもユーザーのブラウザでキャッシュ可能」など… 私は上記も賛同しますし、前職でそう構築した経験もあります。

とはいえ残念ながら何事にもトレードオフがあるため、ここでは主にBFFを置くこと自体のメリットを記載します。

私の思うメリットは「認可の橋渡し(Token Handler)」と「APIアクセスの集約」にあります。

現代のバックエンド(特にマイクロサービス構成)は、ステートレスな Bearer Tokenを要求することが一般的です。SPA単体でこれを実現しようとすると、JSでトークンを扱う(XSSリスク)か、バックエンド側すべてにCookie認証を対応させる(実装コスト増・CORS問題)必要があります。 BFFを挟むことで、「ブラウザとはCookie(セッション)で通信し、バックエンドとはTokenで通信する」という構成が素直に取りやすいです。※もちろんToken Handlerのためにサイドカーや軽量プロキシを扱うことも可能ではあります。

APIアクセスの集約(APIアグリゲーション)に関してはコード的な問題だけでなく、APIが同一VPCのinternalなリクエストで通信出来たり、APIとBFFを同じリージョンにまとめたりとネットワークの効率が優れています。

Reactチームはブラウザから大量の遅いリクエストが飛んでしまう問題をBoomer Fetchingとして問題視しており、ご存知の方も多いと思います。

RSCはBFFとして優れてます

BFFの中であえてNext.jsを選ぶ理由を挙げるとすると、RSCがもたらす開発体験とBFFとしての適性にあります。RSCを「宣言的なBFF」として捉えると非常に優秀です。 従来、BFF層でAPIを叩くためにはExpressを使ったりGraphQLを使うなどの詰め替え業が必要でした。しかしRSCであれば、コンポーネントツリーの中で直接非同期データを取得し、それをPropsとして流し込むだけで済みます。 データの取得とUIの構造がコロケーション(同居)され、かつ型安全にバックエンドAPIのレスポンスをクライアントコンポーネントへ渡せます。

またRSCによってReactを同期的に書くことができて、非同期で発生する難しさをいくつも解消してくれます。

なぜNext.jsじゃなくても良いか

ここまでNext.jsを好意的に書いてきましたが、良くないと感じる部分は存在するのでフェアに記載していきます。

発明を捨てフルスタックフレームワークとしての道を失った

Next.js はApp Router以降、フルスタックフレームワークとしての道を失ったと思っています。

Page RouterまではServerからClientへのPropsの境界が明確で(いわゆるgetServerSidePropsで境界が分かれてた)、貧者の選択としてNext.jsでサーバーを実装する選択も取り得ました。

しかし今回のCVE以降は特に、そうした構成を取る事は明確に難しくなります。

対抗も出現している

たとえばTanstack Startというフレームワークでは、UIライブラリがReactに依存していなかったり(これはTanstack系は共通の思想ですね)、Reactに非依存な層を増やしたい人には嬉しいでしょう。

またサーバー/クライアントの境界を明確に区別しようという思想もあり、こうしたコンセプトもNext.jsより共感する人が多いと思います。

https://tanstack.com/start/latest/docs/framework/react/comparison#server-functions-vs-server-actions

そもそも本当にReactなのかという話もある

上記で紹介したTanstack Startも、他に有力なReact Routerも将来的にRSCを取り入れていく方針ではあります。つまり今の上記フレームワークのシンプルさはRSCに対応してないゆえでもあり、今後どの程度混乱が生じるかは分かりません。

それならいっそ、React以外という道を考える人もいるかもしれません。

ただし、採用市場やフレームワーク自体の完成度を見るに難しい選択にはなると思いますが⋯

ただNext.jsを使う

今フロントエンドでフレームワークやライブラリを選定することは考慮すべきポイントが多くて、難しい時代だなと思います。

きっと色んな言葉が気になってしまうエンジニアも多いと思いますが、最後に私自身の考えを記載しておきます。

ドメインに時間を使う

私が近年大切にしてるテーマの一つに以下の言葉があります。

「どうでもいいことは流行に従い、重大なことは標準に従い、ドメインのことは自ら設計する」

私はカミナシという組織でSaaSを開発していますが、カミナシには「現場ドリブン」という、ドメインに時間を使おうという概念、そのままのバリューが存在します。

私も2025年だけでCS活動やプロダクトディスカバリや商談同席など現場に10件以上訪問して課題に向き合ってきましたが、エンジニアとしての時間をドメインを考えることに対して使っていきたいという想いが年々強まっています。

技術選定の正解探しに時間を溶かすのではなく、選んだ技術を正解にするためのオーナーシップと、何よりユーザーへの価値提供を大切にしていきたい所存です。