Next.jsのversion12から Middleware
と呼ばれるものが導入されました。
Middlewareについて簡単に書くと、
pages
フォルダの特定フォルダ配下に _middleware.js
(tsももちろんOK)を配置すると
リクエスト完了前に実行してくれる、というもの。
ユーザーのリクエストをもとに、レスポンスの書き換え、リダイレクト、ヘッダーの追加、HTMLのストリーミングなどをおこなうことができます。
Middleware | Next.js より引用(DeepL翻訳)
Next.js ver11まで_app.tsxでBasic認証を設定する方法が一般的なイメージでしたが
_appではなく、Middlewareを利用する事で特定のフォルダのみBasic認証をかけるといった事が容易に出来るようになります!
下記のケースだとadmin/配下のみBasic認証をかける事が出来るようになります、便利ですね☺️
pages/
index.tsx
about.tsx
admin/ #このフォルダ配下にはBasic認証がかかる
index.tsx
setting.tsx
_middleware.ts #Basic認証を設定
・・・
検証した環境
1 | nextjs | 12.0.10 |
色々な使い方が出来るよ、という事で公式から参考のコードが公開されています
Next.js12にBasic認証を導入する
以下がBasic認証を行うための _middleware.ts の全文になります!
import { NextRequest, NextResponse } from 'next/server'
export const middleware = (req: NextRequest) => {
if (process.env.ENABLE_BASIC_AUTH !== 'true') {
return NextResponse.next()
}
const basicAuth = req.headers.get('authorization')
if (basicAuth) {
const auth = basicAuth.split(' ')[1]
const [user, password] = Buffer.from(auth, 'base64').toString().split(':')
if (user === process.env.BASIC_AUTH_USER && password === process.env.BASIC_AUTH_PASSWORD) {
return NextResponse.next()
}
}
return new Response('Auth required', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Secure Area"',
},
})
}
あとは .env と next.config.js に環境変数を読み込めるようにします
ENABLE_BASIC_AUTH="false"
BASIC_AUTH_USER="user"
BASIC_AUTH_PASSWORD="password"
module.exports = {
reactStrictMode: false,
env: {
ENABLE_BASIC_AUTH: process.env.ENABLE_BASIC_AUTH,
BASIC_AUTH_USER: process.env.BASIC_AUTH_USER,
BASIC_AUTH_PASSWORD: process.env.BASIC_AUTH_PASSWORD,
},
}
これで全ページでBasic認証が設定出来ます!
Vercelで設定する
Vercelでプロジェクトを選択し
Settings > Environment Variables
で環境変数に値を設定します。
これで先程と同じようにVercelでもBasic認証がかけられるようになります。
余談(Vercel以外での_middlewareについて)
この記事を書いていた少し前(2022/02月初旬頃)に
Serverless Next.js+ Next.js12 + AWS(CloudFront + S3 + Lambda)
という構成でNext.jsのシステムを構築していました。
パッケージ | バージョン |
---|---|
serverless | 2.71.0 |
@sls-next/serverless-component | 3.6.0 |
next | 12.0.9 |
当時、上記の構成で同じように_middleware.tsを使ってBasic認証をかけようとしたところ
Basic認証のキャンセルボタンを押下するとエラー画面ではなく通常通りページが開けてしまう、という問題がありました。
serverlessはアップデートの頻度が多く開発速度が速いイメージがあるため
既に直っているかもしれませんが、
「Vercelだと出来るけど、Serverless Next.js + AWSだと出来ない」というものがちょこちょこあった印象です。
(↓のような記事も上がってますね)
Next.jsのmiddlewareはVercel以外でも問題なく使えるか
結局下記のNext.js11までのBasic認証のかけ方で対応出来たので難を逃れたのですが
Next.jsのデプロイ先はVercelが安定する。
逆にVercel以外でNext.jsを動かすのは結構なチャレンジになる、というのを当時実感していました😅