概要
Next.js(v13.4.12)の環境でMiddlewareを利用してIP制限をかける方法を共有します。
サンプルコード
/src/middleware.ts
import { NextRequest, NextResponse } from 'next/server'
// IPホワイトリスト
const IP_WHITELIST = ['xxx.xxx.xxx.xxx', 'yyy.yyy.yyy.yyy']; // IPアドレスをマスクしています。
export async function middleware(request: NextRequest) {
  const res = NextResponse.next();
  // IPアドレスを取得
  let ip: string = request.ip ?? request.headers.get('x-real-ip') ?? '';
  // プロキシ経由の場合、x-forwarded-forヘッダーからIPアドレスを取得
  if(!ip && forwardedFor){
    const forwardedFor = request.headers.get('x-forwarded-for');
    ip = forwardedFor.split(',').at(0) ?? 'Unknown';
  }
  // 取得したIPアドレスがホワイトリストに含まれているかチェックし、含まれていない場合はアクセス拒否
  if(!IP_WHITELIST.includes(ip)){
      return NextResponse.redirect('https://example.com/access-denied'); // アクセス拒否のページにリダイレクト
  }
  return res;
}
実装の背景
実装するアプリは想定している使用者が限定的でサービスとして利用者を伸ばすものではなかったため、簡単にセキュリティを堅牢にするためにホワイトリスト形式でIP制限をかけることになりました。
実際に実装を進めると、IPの取得にてこずりました。
サンプルリポジトリ・サンプルアプリケーション
Vercelへデプロイしました。
https://middleware-ip-limit-one.vercel.app/
ホワイトリストに指定したIPからアクセスするとNextjsのWelcomeページが表示できますが、それ以外のIPから遷移すれば、「Access Denied」と表示されるようになります。