🔐
Next.jsのMiddlewareで、Basic認証を行う。
はじめに
株式会社ハックツ、エンジニアのみき(@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()
}
でけた👏
ポイント1 matcherの設定
Next.jsのmiddlewareは、config
のmatcher
で、特定のルートに対して処理を実行させることができます。
今回のような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認証を行う方法とそのポイントについてまとめました。
簡単に導入できるので是非参考にしてください。
では、また別の記事で🤡
Discussion