NotionをCMSとしてNext.js × Vercel
でブログアプリケーションを開発したのですが、パブリック公開しない予定なのでBasic認証をかけることにしました。
Webサイト制作ではレンタルサーバーを利用することがほとんどで、その場合はサーバのコンパネからかけられます。
今回の場合はNext.jsのMiddlewareを使えばわりとあっさり実装できたのですが、忘れそうなので記しておきます📝
要件ざっくり
- ブログアプリケーションにBasic認証をかける
- フロントはNext.js、バックエンドはVercelで実装
- npm run devで認証がかかっているとめんどくさいので、本番環境のみ適用する
目次
Next.jsの機能「Middleware」とは
Next.jsのMiddlewareは、リクエストとレスポンスの間で処理を挟む仕組み。
リクエストがサーバーに届いたときに実行され、ページを表示する前に特定の処理を追加できます。
Middlewareの主な用途は下記。
- リクエストの条件をチェック(例:認証)
- リダイレクト処理
- カスタムレスポンスの送信
Middlewareサーバーサイドで動作するため、Basic認証のようなアクセス制限を実現するのに適している✍️
Next.js × Vercelで開発したアプリにBasic認証を実装する
①middleware.ts
を作成する
src/middleware.ts
を作成し下記を記述します。
import { NextResponse } from 'next/server';
export function middleware(req: Request) {
const basicAuth = req.headers.get('authorization');
// Production環境のみ適用
if (process.env.NODE_ENV !== 'production') {
return NextResponse.next();
}
if (basicAuth) {
const auth = basicAuth.split(' ')[1];
const [user, pwd] = Buffer.from(auth, 'base64').toString().split(':');
if (user === process.env.BASIC_AUTH_USER && pwd === process.env.BASIC_AUTH_PASSWORD) {
return NextResponse.next();
}
}
return new NextResponse('Authentication required', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Secure Area"',
},
});
}
開発環境でもBasic認証を適用したい場合は、// Production環境のみ適用
の部分のコードをコメントアウトしてください。
②環境変数の設定
BASIC_AUTH_USER
とBASIC_AUTH_PASSWORD
を環境変数に設定します。
BASIC_AUTH_USER=your-username
BASIC_AUTH_PASSWORD=your-password
👇Vercelの場合は「Settings > Environment Variables」で上記内容を登録。
設定できたら、アプリケーションをVercelにデプロイして完了です◎
注意点:静的ファイルにはNext.jsのMiddlewareが影響しない
Middlewareはリクエスト時にサーバーを介する処理にのみ影響します。
そのため、getStaticProps
やgenerateStaticParams
で生成された静的ページには適用されません。
ただし、VercelではMiddlewareがプロキシレイヤーで動作するため設定が適切であれば問題なく認証が適用されるとのこと。よって今回の場合は問題なし。
まとめ
Next.jsのMiddlewareを使用することで、Vercel上で運用するアプリにBasic認証を簡単に設定できました✨
今回はバックエンドがVercelでしたが、MiddlewareはNext.jsの機能なので、他のバックエンド環境でも応用可能なはず。
AWS Lambdaやオンプレミスのサーバーでも同様の方法で認証を実現できるみたいなので、いつか試してみようと思います。