Skip to content

認証の基礎知識:Cookie、セッション、JWTなど

Webアプリケーションを開発する上で、避けて通れないのが**「認証 (Authentication)」**です。

特に Next.js + NextAuth (Auth.js) のようなモダンな構成を採用する場合、裏側で何が起きているのかを理解していないと、「ログインできない」「テストが通らない」「意図しないログアウトが起きる」といったトラブルに対処できません。

この記事では、認証周りの重要キーワードを、イメージしやすいように整理しました。

1. 認証と認可の基本コンポーネント

Section titled “1. 認証と認可の基本コンポーネント”

まずは、認証情報の「入れ物」と「中身」についてです。

役割:ブラウザ側の「保存容器」

サーバーから送られてくる小さなテキストデータです。ブラウザの中に保存されます。 認証においては、ログイン後にサーバーから発行された「会員証(セッションIDやトークン)」を保存しておく場所として使われます。

  • HttpOnly属性: JavaScriptからのアクセスを禁止する(XSS対策)。
  • Secure属性: HTTPS通信時のみ送信する(盗聴対策)。

役割:サーバー側の「滞在状態」

「このユーザーは現在ログイン中である」という状態そのものを指します。 Webサーバー(HTTP)は本来ステートレス(記憶喪失)なため、リクエストごとに「これはさっきのユーザーだ」と識別する仕組みが必要です。これを実現するのがセッションです。


NextAuthなどのライブラリを使う際、最も重要なアーキテクチャの選択がここにあります。

データベースセッション (Adapter利用)

Section titled “データベースセッション (Adapter利用)”

= サーバーサイドセッション

  • 仕組み: セッションIDだけをCookie(ユーザー)に渡し、実データ(誰が、いつまで有効か)はデータベースの Session テーブルに保存します。
  • メリット: サーバー側から特定のユーザーを強制ログアウト(DBレコード削除)させることができます。セキュリティが高いです。
  • デメリット: ページ遷移のたびにDBアクセスが発生するため、パフォーマンスに影響が出る場合があります。

= クライアントサイドセッション

  • 仕組み: ユーザー情報(ID、権限、有効期限など)をJSON形式で記述し、改ざん防止の署名を付けて暗号化した文字列(トークン)をCookieに保存します。
  • メリット: サーバー(DB)を見に行かなくても、トークンの中身だけで認証検証ができるため高速です。スケーラビリティに優れます。
  • デメリット: 一度発行したトークンは有効期限まで使い続けられるため、サーバー側からの即時無効化(強制ログアウト)が困難です。

3. 認証の入り口(プロバイダー)

Section titled “3. 認証の入り口(プロバイダー)”

ユーザーがどうやって本人確認を行うかの方式です。

= メールアドレス / パスワード認証

昔ながらの ID/Password を入力する方式です。 アプリ開発者が独自に認証ロジック(DBと照合するなど)を実装する必要があります。

  • 自動テスト(Playwright等)での利用: Google等の外部認証はBot検知が厳しいため、E2Eテストのためだけにこの「Credentials認証」を裏口として実装し、テスト環境でのみ有効化する手法がよく取られます。

外部IDプロバイダ認証 (OIDC / OAuth 2.0)

Section titled “外部IDプロバイダ認証 (OIDC / OAuth 2.0)”

= ソーシャルログイン (Google, GitHubなど)

「認証(本人確認)」をGoogleなどの信頼できる第三者に任せる方式です。アプリ側はパスワードを管理しません。

  1. OAuth 2.0: 「認可(データへのアクセス権)」のための仕様。
  2. OIDC (OpenID Connect): OAuth 2.0を拡張して「認証(ID確認)」を行えるようにした仕様。

ユーザーは「Googleのパスポート」を見せて入国するイメージです。セキュリティリスクを外部にオフロードできるため、現代の主流となっています。


実装時によく混乱するキーワードです。

役割:データの運び屋

JWT方式において、暗号化されたデータの塊そのものです。 ログイン時にDBから取得した情報(User IDやRole)は、一度この「トークン」の中に書き込まれます。

役割:データ加工のフックポイント

NextAuthが認証処理を行う途中で、開発者がデータを操作できる関数です。

  1. jwt コールバック: ログイン成功直後や、トークン更新時に呼ばれます。「DBから取得した role 情報を、JWTトークンの中に書き込む」といった処理はここに書きます。
  2. session コールバック: フロントエンドで useSession() 等を使った時に呼ばれます。「JWTトークンの中から role 情報を取り出して、ブラウザで使えるようにする」処理を書きます。
// NextAuthの設定例(イメージ)
callbacks: {
// 1. DBの情報をトークン(荷台)に載せる
async jwt({ token, user }) {
if (user) token.role = user.role;
return token;
},
// 2. トークン(荷台)から取り出してアプリで使う
async session({ session, token }) {
session.user.role = token.role;
return session;
}
}

認証基盤を選定・実装する際は、以下のトレードオフを理解しておくことが重要です。

特徴データベースセッションJWT (JSON Web Token)
状態の場所サーバー (DB)クライアント (Cookie)
パフォーマンスDBアクセスが必要高速 (計算のみ)
強制ログアウト容易 (レコード削除)困難 (期限切れ待ち)
Credentials利用原則不可 (NextAuth)必須