🍪

nextjs-auth0でJWTをCookieに保存しないようにする

2024/01/23に公開

Next.jsアプリケーションでAuth0を利用する際には、Auth0が公式で提供しているauth0/nextjs-auth0が便利です。

このライブラリは標準の設定で動かすと、JWTを暗号化したものをCookieに保存することによってセッションを実現しています。(下記のような値がCookieに焼かれます)

こうすることで、サーバー側でセッションIDと認証情報の紐付けを持たなくとも、セッションを実現することができるというメリットがあります。

多くの場合これで困ることはないと思うのですが、例えばJWTに多くのpayloadを持たせるとCookieのサイズが大きくなってしまう、サーバーサイドでセッションの無効化をしたい 等の理由によって、JWTをCookieに保存したくないというケースも考えられると思います。

nextjs-auth0はこのようなケースにも実は対応しており、SessionStoreインタフェースを実装したクラスを実装して、それを利用したauth0のインスタンスを代わりに用いることで、任意の方法で認証情報を保持することができます。

一般的にはRedisなどのKVストアを利用することになるかと思いますが、ここではインメモリでセッションを実現するサンプルを示します。

import { SessionStore, SessionStorePayload } from '@auth0/nextjs-auth0';

export class InmemoryStore implements SessionStore {
  private store: Map<string, SessionStorePayload> = new Map();

  async get(id: string): Promise<SessionStorePayload | undefined> {
    return this.store.get(id);
  }

  async set(id: string, payload: SessionStorePayload): Promise<void> {
    this.store.set(id, payload);
  }

  async delete(id: string): Promise<void> {
    this.store.delete(id);
  }
}

// 複数回初期化されるとstoreが上書きされてしまうので、一つのインスタンスを使うようにする
export const getInmemoryStore = () => {
  if (global.__inmemoryStore__) {
    return global.__inmemoryStore__;
  }
  return (global.__inmemoryStore__ = new inmemoryStore());
};
import { initAuth0 } from '@auth0/nextjs-auth0';
import { getInmemoryStore } from '@/lib/session-store';

export default initAuth0({ session: { store: getInmemoryStore() } });

このようにすると、セッションIDがCookieに保存されるようになるため、JWTのpayloadが増えてもCookieのサイズは変わらないままにすることができます。

ちなみにこの方法は、nextjs-auth0のEXAMPLES.mdに記載されています。(このドキュメントは結構大事なことがたくさん書いているのでnextjs-auth0を利用する際には一読することをおすすめします)

Discussion