🤖

Next.js 12.2でStableになったMiddleware(Basic認証)のbetaからの主な変更点

2022/07/19に公開

はじめに

表題通り、Next.js 12.2でStableになったMiddlewareのbetaからの変更点を書いていきます。
基本的には公式ドキュメントの通りなのですが、実際に移行してみて少し詰まった部分があったので併せて書いていきます。

以前「Next.js 12でbetaになったMiddleware(Basic認証)を触ってみた」という記事を書いており、そのコードを移行したものになります。
https://zenn.dev/a_da_chi/articles/2b94160f11671e

環境

  • Next.js@12.2
  • Vercel

実際のコード

middleware.ts
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

export const middleware = (req: NextRequest) => {
  if (req.nextUrl.pathname.startsWith('/hoge')) {
    const authorizationHeader = req.headers.get('authorization')

    if (authorizationHeader) {
      const basicAuth = authorizationHeader.split(' ')[1]
      const [user, password] = atob(basicAuth).split(':')

      if (
        user === process.env.BASIC_AUTH_USER &&
        password === process.env.BASIC_AUTH_PASSWORD
      ) {
        return NextResponse.next()
      }
    }

    const url = req.nextUrl
    url.pathname = '/api/hoge'

    return NextResponse.rewrite(url)
  }

  return NextResponse.next()
}
pages/api/hoge.ts
import type { NextApiRequest, NextApiResponse } from 'next'

export default function handler(_: NextApiRequest, res: NextApiResponse) {
  res.statusCode = 401
  res.setHeader('WWW-authenticate', 'Basic realm="Secure Area"')
  res.end('Basic Auth Required')
}

変更点

Nested Middlewareの廃止

betaではpages/_middleware.tsは全てのページで実行され、pages/hoge/_middleware.ts/hoge/.*で実行されるといったように、複数の_middleware.tsを作成することでMiddlewareをネストさせることができていましたが、Stableでは廃止されました。

Stableではpagesディレクトリと同階層に1つだけmiddleware.tsを作成し、middleware.ts内部でどのページで実行するかを記述する方式に変更になりました。

どのページで実行するかの記述方法が公式ドキュメントでは2つ紹介されています。

1つ目はmatcherを使用する方法です。以下のように記述します。

matcher
export const config = {
  matcher: '/hoge/:path*',
}

2つ目はmiddleware関数内でrequest.nextUrl.pathnameを見て処理を振り分ける方法です。この記事ではこちらの記述方法を採用しています。

個人的には2つ以上のページでそれぞれ別の処理を実行したい場合、matcherを使用したとしても結局middleware関数内でrequest.nextUrl.pathnameを見て処理を振り分ける必要があるので最初から2つ目の記述方法を採用しておけばいいのではないかと思います。

Middleware内でレスポンスを返すことができなくなった

betaではBasic認証に失敗した場合は以下のようにMiddleware内で直接レスポンスを返していましたが、Stableではできなくなりました。

beta
return new Response('Basic Auth required', {
  status: 401,
  headers: {
    'WWW-Authenticate': 'Basic realm="Secure Area"',
  },
})

Stableではpages/api配下に専用のエンドポイントを作成し、redirectかrewriteする必要があります。

Edge RuntimeでBufferクラスが使用できなくなった

betaではbase64のデコードにBuffer.fromを使用していましたが、Stableでは使用できなくなりました。

Stableではatobを使用しています。

https://nextjs.org/docs/api-reference/edge-runtime

おわりに

以上です。
上記以外にもcookieを使用する際のインターフェースが変更になっていたりと細かい変更があるようなので、公式ドキュメントも参考にしてみてください。

https://nextjs.org/docs/advanced-features/middleware
https://nextjs.org/docs/messages/middleware-upgrade-guide

それではよいNext.jsライフを!

Discussion