logo

next-authのCookie名を変更したらmiddlewareが動作しなくなった

2023-12-02
a year ago

開発環境

  • next 13.5.4
  • next-auth 4.24.3

前提

NextAuthはv5のベータ版がリリースされていますが、本記事ではv4を扱っています。

v5では変更点が多くあるため、本記事の事象は発生しない可能性ありますのでご了承ください。

また、本記事で紹介する実装は公式が推奨しないと明言しているため、あくまで回避策のひとつとしてご認識ください。

本題

あまり出くわすことがないと思いますが、複数プロジェクトを同時に開発している場合、それぞれでnext-authを利用するとCookie名など重複して認証がうまくいかないケースがあります。

そういったときに、Cookie名をプロジェクトごとにオーバーライドすることが可能です。

以下、optionsの実装サンプルです。

const PROJECT_PREFIX = '__sample-app'

export const options: NextAuthOptions = {
  ...省略,
  cookies: {
    sessionToken: {
      name: `${PROJECT_PREFIX}__next-auth.session-token`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: true
      },
    },
    callbackUrl: {
      name: `${PROJECT_PREFIX}__next-auth.callback-url`,
      options: {
        sameSite: 'lax',
        path: '/',
        secure: true,
      },
    },
    csrfToken: {
      name: `${PROJECT_PREFIX}__next-auth.csrf-token`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: true,
      },
    },
    pkceCodeVerifier: {
      name: `${PROJECT_PREFIX}__next-auth.pkce.code_verifier`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: true,
        maxAge: 900,
      },
    },
    state: {
      name: `${PROJECT_PREFIX}__next-auth.state`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: true,
        maxAge: 900,
      },
    },
    nonce: {
      name: `${PROJECT_PREFIX}__next-auth.nonce`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: true,
      },
    },
  },
  ...省略
};
next-auth.ts

※何度も繰り返しになりますが、公式は推奨していません。


Cookie名を変更できましたが、その結果、middlewareで認証が通らなくなる場合があります。

next-authの内部的に、Cookie名の変更がmiddlewareでの処理まで共有されていないようです。

そこで、以下のようにmiddlewareも書き換える必要があります。

import { withAuth } from 'next-auth/middleware';

const PROJECT_PREFIX = '__sample-app'

export default withAuth({
  callbacks: {
    authorized: ({ req: { cookies } }) => {
      const sessionToken = cookies.get(
        `${PROJECT_PREFIX}__next-auth.session-token`,
      );
      return !!sessionToken?.value;
    },
  },
});

export const config = {
  matcher: ['/((?!login).*)'], // ここは認証から除外するURLを入れる
};
middleware.ts

やっていることとしては、Cookie名を変えてしまうとmiddlewareの認証が全て通らなくなってしまうので、手動でsession-tokenの値の有無を確認するようにしています。

参照