NextjsのmiddlewareからLaravel Sanctumの認証を通す方法

6821 ワード

やりたいこと

nextjsのミドルウェアで、LaravelSanctum(SPA認証)のログイン済みかどうかの判定で振り分けたい。

詰まったところ

クライアントサイドからのリクエストの場合には、ログイン後SET-COOKIEが含まれたレスポンスが帰ってきてるため一度ログインしてしまえば、移行認証情報について特段気にすることはない。
ブラウザからのリクエストではなくnode serverからapiサーバーに送信されるリクエストについては、何もしないとサラのリクエストをしてしまうようで、Sanctumがチェックする認証情報を適宜指定してあげなければいけなかった。

方法

apiServer.ts
import axios from "axios";

export const apiServer = axios.create({
    baseURL: process.env.API_ENDPOINT,
    responseType: 'json',
    withCredentials: true,
    headers: {
        "Content-Type": "application/json",
    }
})
pages/_middleware.ts
import {NextFetchEvent, NextRequest, NextResponse} from "next/server";
import fetchAdapter from "@vespaiach/axios-fetch-adapter";
import {apiServer} from "../../utils/apiServer";

export default async function middleware(req: NextRequest, ev: NextFetchEvent) {
    apiServer.defaults.adapter = fetchAdapter
    const {data} = await apiServer.get('http://web:80/api/auth/me', {
        headers: {
            Cookie: req.headers.get('cookie') ?? '',
            referer: req.headers.get('referer') ?? ''
        }
    })

    if (!data.authenticated) {
        return NextResponse.redirect(`${process.env.APP_URL}/auth/login`)
    }
    return NextResponse.next()
}

下記の記事に書いてある通り、sanctumを使って認証する場合にLaravel側では、Cookieに含まれる情報に加えてrefererもチェックするので最低限CookieとRefererをヘッダーにセットしてあげる必要がある。