かつて、Next.js 12でミドルウェアを使ったBasic認証の設定方法を 記事 にまとめましたが、Next.js 13になって、ミドルウェアの設定方法に微妙な変更があったため調査しました。
変更点
middleware.tsの位置変更
前回の方法 をそのまま使用すると、
error - Nested Middleware is not allowed, found: pages/_middleware Please move your code to a single file at /src/middleware instead. Read More - https://nextjs.org/docs/messages/nested-middleware
と、エラーが表示されます。
対応するためには、ミドルウェアの位置を pages/_middleware.ts から src/middleware.ts に移動する必要があります。
bufferモジュールの削除
pages/_middleware.ts から src/middleware.ts に移動し、ユーザー名、パスワードを入力すると、
error - Error: The edge runtime does not support Node.js 'buffer' module. Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
と、エラーが表示されます。
Node.jsのグローバルクラスが使えないので、Bufferを使うのを止め、atobに置き換えます。
つまり、
const [ user, password ] = Buffer.from(auth, 'base64').toString().split(':');
の部分を、
const [ user, password ] = atob(auth).split(':');
とします。
結論
src/middleaware.ts
import { NextRequest, NextResponse } from 'next/server'; const USER_NAME = 'user'; const PASSWORD = 'password'; export function middleware(req: NextRequest) { const basicAuth = req.headers.get('authorization'); if (basicAuth) { const auth = basicAuth.split(' ')[1]; const [ user, password ] = atob(auth).split(':'); if (user === USER_NAME && password === PASSWORD) { return NextResponse.next(); } } return new Response('Auth required', { status: 401, headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' } }); }
こちらのコードを、src/middleaware.tsに設置すればBasic認証が掛かります。
実際に使用する場合は、USER_NAME、PASSWORDを、ファイルに直書きするのではなく、envファイルに書き込んだ方が安全です。