🍪
nextjs-auth0でJWTをCookieに保存しないようにする
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