【Middleware使用】Next.js12でBasic認証を導入(ローカル,vercel 両対応)

投稿日
【Middleware使用】Next.js12でBasic認証を導入(ローカル,vercel 両対応)

Next.js ver13系ではこの記事の方法が使えなくなりました。

13系の人は以下記事を参考にしてみて下さいmm






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

色々な使い方が出来るよ、という事で公式から参考のコードが公開されています

examples/edge-functions at main · vercel/examples




Next.js12にBasic認証を導入する

以下がBasic認証を行うための _middleware.ts の全文になります!

pages/_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 に環境変数を読み込めるようにします

.env
ENABLE_BASIC_AUTH="false"
BASIC_AUTH_USER="user"
BASIC_AUTH_PASSWORD="password"
next.config.js
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のシステムを構築していました。


パッケージバージョン
serverless2.71.0
@sls-next/serverless-component3.6.0
next12.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を動かすのは結構なチャレンジになる、というのを当時実感していました😅

プロフィール画像
Yuki Takara
都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。