2026年10月8日にMDNのHTTP認証・Cookie、NIST SP 800-63B、OWASPの認可・セッション管理本文を再確認した。セッションCookie、JWT、OAuth/OIDCは異なる層の道具で、本人確認(authentication)、要求ごとの認可(authorization)、セッションの更新・失効、CSRF/XSS対策を別に設計する。SecureやHttpOnly、SameSiteは有効な防御層だが、Cookie属性だけで認可漏れやサーバー側の脆弱性は消えない。
ログインはできたのに、別の会社の記事を編集できてしまう。こうした不具合は、本人確認の成功を、その後の操作の許可と取り違えると起こります。Web認証を選ぶときは、本人確認・ログイン状態・操作権限・失効を分けると、ライブラリに任せる部分と自社で決める部分が見えます。
30秒で要点
- 認証は利用者の身元を確かめる処理。認可は「この対象に、この操作をしてよいか」を確かめる処理です。
- セッションはログイン状態を維持する仕組み、JWTは情報を表す形式、Cookieはブラウザとの受け渡し手段です。三つは組み合わせて使えます。
- 導入時は成功するログインに加え、別組織へのアクセス、権限変更、期限切れ、ログアウト後の拒否を確認します。
認証の後に、対象と操作の確認がある
社内の記事管理アプリを考えます。利用者Aがログインできても、「会社Bの下書きを読む」「自社の記事を公開する」「他の利用者を管理者にする」は別々の権限です。役職名だけでなく、所属する組織、記事との関係、操作の種類を見ます。
OWASPの認可ガイドは、必要な権限に絞り、明示的に許可できない要求を拒否し、各リクエストで権限を確認する考え方を示しています。確認する場所はサーバーやデータアクセスの境界です。画面のボタンを隠す処理は、利用者を迷わせないための補助になります。図の最後の「公開条件」は認証技術そのものではなく、アプリの業務ルールです。たとえば「公開権限がある」と「この版がレビュー済み」は両方確認します。確認後に記事が変わる可能性があるなら、更新時にも同じ版・状態であることを確かめる仕組みが必要です。
セッション、JWT、Cookieを別の軸で比べる
セッションは、一度ログインした利用者を後続の通信でも識別する仕組みです。サーバーに状態を保存し、ブラウザへ推測困難なIDだけを渡す構成があります。サーバー側の保存先を共有する設計なら複数台で扱えるため、「セッションは規模を大きくできない」とは限りません。
JWT(JSON Web Token)は、利用者IDや発行者などの情報を表す形式です。署名による改ざん検知と暗号化は別の処理で、署名だけのJWTの内容は秘密になりません。JWTの利用指針に沿い、許可したアルゴリズムと鍵、発行者、受取先、用途に合った検証を行います。有効期限など、採用したプロトコルが要求する項目も確認します。文字列をデコードして利用者IDを取り出すだけでは検証になりません。
表が収まらない場合は、横にスクロールできます
| 比べる点 | サーバーに状態を置くセッション | JWTを使うセッションやAPIアクセス |
|---|---|---|
| 要求を受けたとき | IDに対応する状態・期限を照会する | 検証済みライブラリでトークンを検証し、必要な追加照会を行う |
| 権限を変えたいとき | 保存状態や権限を更新できる | トークン中の古い権限が残る場合がある |
| 失効させたいとき | 保存したセッションを無効化する | 短い有効期限、失効情報の照会などを組み合わせる |
| 設計上の負担 | 保存先の可用性と照会コスト | 鍵管理、更新、失効、情報の鮮度 |
Cookieは、ブラウザが条件に合う通信へ値を付ける仕組みです。IDもJWTも保存できます。Auth.jsのセッション方式にも、Cookieを使うJWT方式とデータベース方式があります。「CookieかJWTか」だけでは、保存場所と状態管理が混ざってしまいます。
ブラウザに何を持たせるか
自社サーバーを持つWebアプリでは、ブラウザにはセッション識別子を持たせ、外部APIの資格情報はサーバー側で扱う構成を検討できます。ブラウザからAPIへ直接接続する構成では、SDKの保存方式、期限、更新方法、スクリプトから読める範囲まで確認します。
localStorageやsessionStorageはJavaScriptからアクセスできます。OWASPのWeb Storageの注意点が示すように、XSS(ページで意図しないスクリプトが動く問題)で資格情報が盗まれる可能性があります。「JWTだからlocalStorageへ保存する」という決め方は避けます。
Cookieには、用途に応じてSecure、HttpOnly、SameSiteを設定します。セッション管理の指針に沿って、HTTPS、認証後のID更新、期限、サーバー側の失効も扱います。
Cookieが自動送信される状態変更では、CSRF(利用者の意図しない要求を送らせる攻撃)への対策が必要です。フレームワークのCSRF保護を確認し、構成に応じてトークンなどを検証します。SameSiteは通常、追加の防御層として扱います。
OAuth、OIDC、WebAuthnは担当する役割が違う
OAuth 2.0は、別のサービスの資源へアクセスする権限を委譲するための仕組みです。OpenID Connect(OIDC)は、その上に本人確認の情報を伝える仕組みを加えます。OIDCのIDトークンはログインした人に関する情報、アクセストークンは対象APIへのアクセスに使う資格情報です。同じJWT形式でも、用途を入れ替えて使えません。OIDC Coreでは、発行者・受取先・期限や、要求に含めたnonceとの一致などを検証します。
外部ログインの連携は、認可コードフローと、コードを受け取る相手を結び付けるPKCEに対応した公式SDKから始めます。OAuthのセキュリティ指針 RFC 9700では、秘密を保管できないpublic clientにPKCEを要求し、秘密を保管できるconfidential clientにも推奨しています。戻り先URLの照合や、ログイン要求との結び付けも必要です。PKCEの有効化だけでアプリ全体の保護が終わるわけではありません。
WebAuthnは、サービスにひも付いた公開鍵の資格情報を登録し、認証に使うWeb APIです。パスキーによるログインの基盤になります。サイトはパスワードを受け取る代わりに、要求に対して返された署名などを検証します。W3Cの仕様が扱う本人確認と、ログイン後のセッション・操作権限は分けて設計します。端末を失ったときの回復経路も、利用者に説明できる形で用意します。
なお、CORSはブラウザが別オリジンの応答をスクリプトへ共有する条件を扱います。別オリジンのAPIへブラウザからアクセスする場合、CORS設定はJWTの採用とは別に確認します。CORS設定もサーバー側の認可を代替しません。詳しくはCORSが許可するものの整理で確認できます。
ライブラリを選ぶ前に、運用する範囲を決める
NextAuth.jsを含むAuth.jsのようなライブラリでは、自社アプリでセッション方式や接続先を選びます。Supabase Authのようなサービスを利用する場合も、アプリの認可ルールは必要です。ブランド名より、次の条件で比べると選択を説明しやすくなります。
表が収まらない場合は、横にスクロールできます
| 確認する条件 | 選定前に決めること |
|---|---|
| 利用者 | 社内IDで統一するか、一般利用者の登録を受け付けるか |
| 停止と回復 | 退職・端末紛失・資格情報漏えいに誰が対応するか |
| 権限 | 組織・対象・操作ごとのルールをどこで確認するか |
| 配置と維持 | 実行環境との互換、データの置き場所、更新・障害対応の担当 |
たとえばSupabaseのNext.js向けSSRガイドは、ブラウザ用とサーバー用の処理を分け、サーバーでgetSession()の値だけを信用しないよう説明しています。検証用APIと最新の利用者情報を取得するAPIの役割も異なります。利用者別の応答や更新したCookieを共有キャッシュへ混ぜない設計も必要です。
自社でパスワードを扱う場合、保存・照合・再設定をまとめて保守します。OWASPのパスワード保存ガイドでは、新規構成でArgon2idなどを検討し、bcryptは既存構成との条件も示しています。単に「ハッシュ関数を使った」で終えず、設定値と更新方法まで確認します。
一つの操作から、拒否されるケースを確かめる
まず記事公開のような一つの操作を選び、検証用アカウントと検証用データだけで、次の期待結果を整理します。
表が収まらない場合は、横にスクロールできます
| ケース | 期待する結果 |
|---|---|
| 未ログイン、期限切れ、失効済み | 保護された操作を拒否する |
| ログイン済みだが別組織の記事 | 記事の内容を返さず、公開も拒否する |
| 同じ組織だが閲覧権限だけ | 閲覧は許可し、公開は拒否する |
| 公開権限はあるが未承認の版 | 業務ルールに従って公開を止める |
| 必要な権限と公開条件がそろう | 指定した記事・版だけを公開する |
| 権限を取り消した後の古いログイン状態 | 定めた失効時間内に拒否へ変わる |
ここではAPIの応答だけでなく、保存状態が変わっていないことも見ます。記録するなら「期待どおり拒否した件数/試した拒否ケース数」と、権限を取り消してから拒否されるまでの時間を残します。この割合は試した範囲の確認結果であり、アプリ全体の安全性を表す確率ではありません。
ログインを一度通すことから、許可してよい操作だけが通り、止めるべき時点で止まることへ。方式の名前を選ぶ前に、この条件をチームで共有すると実装とレビューの焦点がそろいます。