🔐

Next.jsのMiddlewareで、Basic認証を行う。

2024/12/15に公開

はじめに

株式会社ハックツ、エンジニアのみき(@take_cantik)です。⛏️
今回は、Next.jsのMiddlewareで、Basic認証を行う方法についてまとめました。

ちなみに環境は以下の通りです。

  • Next v14
  • App Router

結論

src/ 直下(app/と同階層)に、 middleware.ts を作成し、以下をコピペで完了🙆‍♂️

middleware.ts
import { NextRequest, NextResponse } from 'next/server'

export const config = {
  matcher: [
    /*
     * 下記のパスをmiddlewareの対象外とする設定
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'
  ]
}

export function middleware(req: NextRequest) {
  const basicAuth = req.headers.get('Authorization')

  // 認証情報がない場合は、認証情報を要求する
  if (!basicAuth) {
    return NextResponse.json(
      { error: '認証が必要です。' },
      { headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' }, status: 401 }
    )
  }

  // 認証情報を取得
  const authValue = basicAuth.split(' ')[1]
  const [user, password] = atob(authValue).split(':')

  const isAuthorized =
    user === process.env.BASIC_AUTH_USERNAME && password === process.env.BASIC_AUTH_PASSWORD

  // 認証情報が不正な場合は、エラーレスポンスを返す
  if (!isAuthorized) {
    return NextResponse.json(
      { error: '入力値が不正です。正しい認証情報を入力してください。' },
      { headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' }, status: 401 }
    )
  }

  return NextResponse.next()
}

でけた👏

Basic認証の画面

ポイント1 matcherの設定

Next.jsのmiddlewareは、configmatcherで、特定のルートに対して処理を実行させることができます。

https://nextjs.org/docs/app/building-your-application/routing/middleware#matching-paths

今回のようなBasic認証は、APIルートや静的ファイルには適応したくないので、
正規表現を使用して、それら以外のパスのみ適応されるように設定しています。

export const config = {
  matcher: [
    /*
     * 下記のパスをmiddlewareの対象外とする設定
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'
  ]
}

ポイント2 セキュリティ上の注意

環境変数名

Next.jsのmiddlewareはサーバーサイドで動くため、NEXT_PUBLICプレフィックスの使用は避けましょう。
NEXT_PUBLICした環境変数はクライアントサイドに公開されてしまいます。

通信プロトコル

Basic認証はユーザー名とパスワードがBase64形式(暗号化されてない)で送信されるため、
本番運用でBasic認証を使用する場合には、HTTPではなくHTTPS通信を使用しましょう。

さいごに

今回は、Next.jsのMiddlewareで、Basic認証を行う方法とそのポイントについてまとめました。
簡単に導入できるので是非参考にしてください。

では、また別の記事で🤡

Hackz Inc.

Discussion