コンパイラかく語りき

import { Fun } from 'programming'

【Next.js】API CORS 設定

Next.js で作成した API が別ドメインからアクセスされる時、CORS の問題が発生すると思います。

対応策について調べてみたところ、設定ファイルである next.config.jsheader 項目が利用できる、との情報を見つけました。

nextjs-ja-translation-docs.vercel.app

コードはこのような感じ。

module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Access-Control-Allow-Origin',
            value: /* ここにドメイン情報 */
          },
        ],
      },
      // その他、CORS設定
     ],
  },
}

しかし自分の環境では動かず…。CORS問題が解決しませんでした。

次に nextjs-cors というパッケージを発見。

www.npmjs.com

コードを見てみると、内部的に cors パッケージを利用しています。

github.com

Express の organization 内のレポジトリですが、express だけではなくconnect にも利用可能とあります。

なるほど、このパッケージを Next.js の middleware として使っているんですね。ただ、これくらいなら nextjs-cors を入れずとも自前で書けそう…?

さらに調べてみると、Next.js のレポジトリに CORS 設定のサンプルがありました!

github.com

このサンプルのように実装したのが以下のコード。

import Cors from 'cors'
import { NextApiRequest, NextApiResponse } from 'next'

/** CORS 設定 */
const cors = Cors<NextApiRequest>({
  // env ファイルの情報を利用
  origin: process.env.NEXT_PUBLIC_API_ARROW_ORIGIN,
  // メソッドは一旦全て…
  methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
  // cookie 情報を含める
  credentials: true,
})

/**
 * Next.js API Route のための CORS 設定ミドルウェア
 */
export const runCorsMiddleware = (
  req: NextApiRequest,
  res: NextApiResponse
) => {
  return new Promise((resolve, reject) => {
    cors(req, res, (result: unknown) => {
      if (result instanceof Error) {
        return reject(result)
      }
      return resolve(result)
    })
  })
}

利用側はこのような感じに。

/** API パス */
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  await runCorsMiddleware(req, res)
  
  // 以下、API の処理内容

API のパス毎に設定するのは微妙な気がしますが… 一旦 CORS 問題は解決できました。