【Next.js】SSG(ISR)でも簡単にベーシック認証やverifyIdTokenを行う方法

2022-04-16

Middleware を使用すれば意外とあっさり組めちゃいます。

import fetchAdapter from "@vespaiach/axios-fetch-adapter"; import axios from "axios"; import { NextRequest, NextResponse } from "next/server"; async function middleware(req: NextRequest): Promise<Response> { // revalidate 時またはファイルを参照している場合は全通しする if ( req.headers.has("x-prerender-revalidate") || req.nextUrl.pathname.includes(".") ) { return NextResponse.next(); } /* * ベーシック認証 start */ // api の場合は認証を行わない if (!req.nextUrl.pathname.startsWith("/api")) { const authRequiredResponse = new Response("Auth required", { headers: { "WWW-Authenticate": 'Basic realm="Secure Area"', }, status: 401, }); const basicAuth = req.headers.get("authorization"); if (!basicAuth) { return authRequiredResponse; } const auth = basicAuth.split(" ")[1]; const [user, password] = Buffer.from(auth, "base64").toString().split(":"); if ( password !== process.env.BASIC_AUTH_PASSWORD || user !== process.env.BASIC_AUTH_USER ) { return authRequiredResponse; } } /* * ベーシック認証 end */ /* * verifyIdToken start */ // ログイン不要なページは verify を行わない if ( req.nextUrl.pathname !== "/redirect" && req.nextUrl.pathname !== "/signin" && req.nextUrl.pathname !== "/signout" ) { try { const axiosInstance = axios.create({ adapter: fetchAdapter, }); await axiosInstance.get(`${req.nextUrl.origin}/api/verifyIdToken`, { headers: { cookie: `idToken=${req.cookies.idToken}; refreshToken=${req.cookies.refreshToken}`, }, }); return NextResponse.next(); } catch { return NextResponse.redirect(`${req.nextUrl.origin}/signout`); } } /* * verifyIdToken end */ return NextResponse.next(); } export default middleware;

ポイントは req.headers.has("x-prerender-revalidate") です。

この実装によって revalidate 時に認証を回避することが可能となります。Failed to revalidate route of a specific locale

ぜひ参考になりましたら幸いです。

© 2018 kk-web