🐲
[Next.js] middleware複雑化してない?NEMOを紹介する
この記事を読んでほしい人
Next.jsで開発をしていて、middlewareが肥大化してしまっている人にぜひ読んでほしいです。
NEMOとは?
実装してみる
何はともあれ実際のコードを見た方が理解が早いので、以下の2つを実装したコードを紹介します。
- 全画面に対してベーシック認証をする
- ログイン状態で
/login
に遷移した場合、/
にリダイレクトする
全画面に対してベーシック認証をする
middleware.ts
import { type MiddlewareFunctionProps, createMiddleware } from "@rescale/nemo"
import { NextResponse } from "next/server"
const basicAuthentication = async ({ request, response }: MiddlewareFunctionProps) => {
const basicAuth = request.headers.get("authorization")
if (basicAuth) {
const [user, password] = atob(basicAuth.split(" ")[1]).split(":")
if (user === process.env.BASIC_AUTH_USERNAMpE && password === process.env.BASIC_AUTH_PASSWORD) {
return response // responseはNextResponse.next()と同じ型で同義です
}
}
return new NextResponse("Basic Authentication Required.", { status: 401, headers: { "WWW-authenticate": 'Basic realm="Secure Area"' } })
}
export const middleware = createMiddleware({
"*": [basicAuthentication], // 全画面適用なのでワイルドカード"*"を指定しています
})
/login
に遷移した場合、/
にリダイレクトする
ログイン状態でmiddleware.ts
import { type MiddlewareFunctionProps, createMiddleware } from "@rescale/nemo"
import { NextResponse } from "next/server"
const basicAuthentication = async ({ request, response }: MiddlewareFunctionProps) => {
const basicAuth = request.headers.get("authorization")
if (basicAuth) {
const [user, password] = atob(basicAuth.split(" ")[1]).split(":")
if (user === process.env.BASIC_AUTH_USERNAMpE && password === process.env.BASIC_AUTH_PASSWORD) {
return response
}
}
return new NextResponse("Basic Authentication Required.", { status: 401, headers: { "WWW-authenticate": 'Basic realm="Secure Area"' } })
}
export const middleware = createMiddleware({
"*": [basicAuthentication],
+ "/login": [
+ async ({ request }: MFProps) => {
+ const user = await userService.getMe() // ログインユーザーを取得します
+ if (!user) return NextResponse.next()
+ const url = request.nextUrl.clone()
+ url.pathname = "/"
+ return NextResponse.redirect(url)
+ },
+ ],
})
最後に
今回実装した部分だけだとあまり良さが伝わらないですが、ユーザー権限によって画面制御が必要なプロジェクトなどにおいては、かなり有用なのではと思います。
ぜひ試してみてください。
Discussion