Web開発において「認証」と「認可」という言葉は頻繁に登場しますが、これらの違いを正確に説明できる方は意外と少ないのではないでしょうか。ログイン機能を実装する際に「ユーザーを認証する」とは何を意味するのか、「このリソースへのアクセスを認可する」とはどういうことなのか、明確に区別できていることがセキュアなWeb開発の第一歩です。

この記事では、認証と認可の違いから始まり、代表的な認証方式(Basic認証、フォーム認証、トークン認証)の比較、認証・認可のフローを図解で解説します。さらに、開発者ツールを使って実際の認証・認可の挙動を確認する方法も紹介しますので、ぜひ手を動かしながら理解を深めてください。

認証(Authentication)と認可(Authorization)の違い

認証と認可は、アクセス制御において異なる役割を担う概念です。まずはこの2つの違いを明確にしましょう。

認証(Authentication)とは

認証(Authentication、略してAuthN)とは、「あなたは誰ですか?」という問いに答えるプロセスです。ユーザーが主張するアイデンティティ(ID)が正しいかどうかを検証します。

認証の具体例は以下の通りです。

  • ユーザー名とパスワードによるログイン
  • 指紋認証や顔認証などの生体認証
  • ワンタイムパスワード(OTP)による多要素認証
  • ICカードやセキュリティキーによる認証

認証が成功すると、システムは「このリクエストはユーザーAから送信されたものだ」と識別できるようになります。

認可(Authorization)とは

認可(Authorization、略してAuthZ)とは、「あなたは何ができますか?」という問いに答えるプロセスです。認証されたユーザーが、特定のリソースに対してどのような操作を許可されているかを決定します。

認可の具体例は以下の通りです。

  • 一般ユーザーは自分のプロフィールのみ編集可能
  • 管理者はすべてのユーザー情報を閲覧・編集可能
  • 無料プランのユーザーは基本機能のみ利用可能
  • 有料プランのユーザーはプレミアム機能も利用可能

認可は認証の後に行われることが一般的ですが、認証なしでも認可が適用されるケースもあります(例:未ログインユーザーに対して公開ページへのアクセスを許可する)。

認証と認可の比較表

項目 認証(Authentication) 認可(Authorization)
目的 ユーザーの身元を確認する ユーザーの権限を確認する
問い 「あなたは誰?」 「あなたは何ができる?」
タイミング 最初に実行される 認証の後に実行される
失敗時のHTTPステータス 401 Unauthorized 403 Forbidden
ログイン処理 アクセス権限チェック

認証と認可の関係を図解で理解する

認証と認可の関係を、図解で確認しましょう。

flowchart TD
    A["リクエスト受信"] --> B{"認証(Authentication)<br>あなたは誰?"}
    B -->|成功| C["ユーザーを識別<br>(例: user_id=123)"]
    B -->|失敗| D["401 Unauthorized<br>「認証に失敗しました」"]
    C --> E{"認可(Authorization)<br>あなたは何ができる?"}
    E -->|許可| F["リソースへアクセス<br>(処理を実行)"]
    E -->|拒否| G["403 Forbidden<br>「権限がありません」"]

重要なポイントは、401 Unauthorized403 Forbiddenの違いです。名前が紛らわしいですが、401は「認証」の失敗を示し、403は「認可」の失敗を示します。つまり、401は「あなたが誰かわからない」、403は「あなたが誰かはわかったが、その操作は許可されていない」という意味になります。

代表的な認証方式の比較

Web開発で使用される代表的な認証方式について、それぞれの特徴と使いどころを解説します。

Basic認証

Basic認証は、HTTPプロトコルに組み込まれた最もシンプルな認証方式です。ユーザー名とパスワードをBase64でエンコードして、Authorizationヘッダーに含めて送信します。

sequenceDiagram
    participant Browser as ブラウザ
    participant Server as サーバー
    Note over Browser,Server: 1. クライアントがリソースにアクセス
    Browser->>Server: GET /admin/dashboard
    Note over Browser,Server: 2. サーバーが認証を要求
    Server-->>Browser: 401 Unauthorized<br>WWW-Authenticate: Basic realm="Admin Area"
    Note over Browser: 3. ブラウザがログインダイアログを表示
    Note over Browser,Server: 4. 認証情報を含めて再リクエスト
    Browser->>Server: GET /admin/dashboard<br>Authorization: Basic dXNlcjpwYXNzd29yZA==
    Note over Browser,Server: 5. 認証成功でリソースを返却
    Server-->>Browser: 200 OK(コンテンツ)

Basic認証のリクエストヘッダーは以下のようになります。

1
2
3
GET /admin/dashboard HTTP/1.1
Host: example.com
Authorization: Basic dXNlcjpwYXNzd29yZA==

dXNlcjpwYXNzd29yZA==user:passwordをBase64エンコードした値です。

Basic認証のメリット

  • 実装が非常にシンプル
  • ほぼすべてのHTTPクライアントでサポートされている
  • サーバー側の設定だけで導入可能(Webサーバーレベルで設定可能)

Basic認証のデメリット

  • 認証情報がBase64でエンコードされるだけで暗号化されない(HTTPS必須)
  • ログアウト機能がない(ブラウザを閉じるまで認証情報がキャッシュされる)
  • カスタマイズ性が低い(UIはブラウザ標準のダイアログ)
  • CSRF攻撃に対して脆弱

Basic認証の使いどころ

  • 開発環境やステージング環境へのアクセス制限
  • 簡易的な管理画面の保護
  • API間通信での認証(サーバー間通信)

フォーム認証

フォーム認証は、HTMLフォームを使用してユーザー名とパスワードを送信し、サーバー側でセッションを生成する認証方式です。最も一般的なWeb認証方式の1つです。

sequenceDiagram
    participant Browser as ブラウザ
    participant Server as サーバー
    Note over Browser,Server: 1. ユーザーがログインページにアクセス
    Browser->>Server: GET /login
    Server-->>Browser: 200 OK + ログインフォーム
    Note over Browser,Server: 2. ユーザーが認証情報を送信
    Browser->>Server: POST /login<br>username=user, password=pass
    Note over Browser,Server: 3. サーバーがセッションを生成してCookieを返却
    Server-->>Browser: 302 Found<br>Set-Cookie: session_id=abc123
    Note over Browser,Server: 4. 以降のリクエストにはセッションIDが自動で含まれる
    Browser->>Server: GET /dashboard<br>Cookie: session_id=abc123
    Server-->>Browser: 200 OK(コンテンツ)

フォーム認証のメリット

  • カスタマイズ可能なUI(ブランディングに合わせたデザイン)
  • ログアウト機能の実装が容易
  • 「ログイン状態を保持する」機能の実装が可能
  • 多要素認証との組み合わせが容易

フォーム認証のデメリット

  • セッション管理の実装が必要
  • サーバー側でセッション情報を保持する必要がある(スケーラビリティの課題)
  • CSRF対策が必要

フォーム認証の使いどころ

  • 一般的なWebアプリケーションのログイン
  • ユーザー向けの管理画面
  • ECサイトやSNSなど、ユーザー体験を重視するサービス

トークン認証

トークン認証は、認証成功後にサーバーがトークン(文字列)を発行し、クライアントがそのトークンを使って認証を行う方式です。特にSPA(Single Page Application)やモバイルアプリ、API認証で広く使用されています。

代表的なトークン認証方式として、Bearer Tokenと**JWT(JSON Web Token)**があります。

sequenceDiagram
    participant Client as クライアント(SPA)
    participant Server as サーバー
    Note over Client,Server: 1. ユーザーがログインリクエストを送信
    Client->>Server: POST /auth/login<br>{"username": "user", "password": "pass"}
    Note over Client,Server: 2. サーバーがトークンを発行
    Server-->>Client: 200 OK<br>{"access_token": "eyJhbGc...", "token_type": "Bearer"}
    Note over Client: 3. クライアントがトークンを保存<br>(メモリ/localStorage等)
    Note over Client,Server: 4. 以降のリクエストにはAuthorizationヘッダーでトークンを送信
    Client->>Server: GET /api/users/me<br>Authorization: Bearer eyJhbGc...
    Note over Client,Server: 5. サーバーがトークンを検証してリソースを返却
    Server-->>Client: 200 OK<br>{"id": 123, "name": "User"}

トークン認証のリクエストヘッダーは以下のようになります。

1
2
3
GET /api/users/me HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

トークン認証のメリット

  • ステートレス:サーバー側でセッション情報を保持する必要がない
  • スケーラビリティ:ロードバランサー配下の複数サーバーで認証情報を共有しやすい
  • クロスドメイン対応:異なるドメイン間でも認証情報を共有可能
  • モバイルアプリとの相性が良い

トークン認証のデメリット

  • トークンの安全な保存場所の検討が必要
  • トークンの失効処理が複雑(JWTの場合、発行後の無効化が困難)
  • トークンサイズが大きくなる場合がある(JWTの場合)

トークン認証の使いどころ

  • SPA(Single Page Application)の認証
  • モバイルアプリケーションの認証
  • マイクロサービス間の認証
  • サードパーティAPIへのアクセス

認証方式の比較表

項目 Basic認証 フォーム認証 トークン認証
実装の容易さ 非常に簡単 中程度 やや複雑
カスタマイズ性 低い 高い 高い
ステートレス はい いいえ はい
スケーラビリティ 高い 中程度 高い
ログアウト 困難 容易 やや複雑
モバイル対応 可能 困難 最適
SPA対応 可能 やや困難 最適
CSRF耐性 弱い 対策必要 高い
主な用途 開発環境保護 Webアプリ API/SPA/モバイル

認可の実装パターン

認証によってユーザーを識別した後は、認可によってアクセス権限を制御します。代表的な認可の実装パターンを紹介します。

ロールベースアクセス制御(RBAC)

ロールベースアクセス制御(Role-Based Access Control, RBAC)は、ユーザーにロール(役割)を割り当て、ロールに対して権限を付与する方式です。

flowchart TD
    subgraph Users["ユーザー"]
        Alice["Alice"]
        Bob["Bob"]
        Charlie["Charlie"]
    end
    subgraph Roles["ロール"]
        Admin["Admin"]
        Editor["Editor"]
        Viewer["Viewer"]
    end
    subgraph Permissions["権限"]
        Perm["create / read / update / delete"]
    end
    Alice --> Admin
    Bob --> Editor
    Charlie --> Viewer
    Admin --> Perm
    Editor --> Perm
    Viewer --> Perm

ロールと権限のマッピング例:

ロール create read update delete
Admin
Editor ×
Viewer × × ×

RBACはシンプルで理解しやすい一方、複雑な権限要件には対応しづらい場合があります。

属性ベースアクセス制御(ABAC)

属性ベースアクセス制御(Attribute-Based Access Control, ABAC)は、ユーザー属性、リソース属性、環境属性などを組み合わせて権限を判定する方式です。

flowchart TD
    subgraph Attributes["属性"]
        User["ユーザー属性<br>・部署<br>・役職<br>・資格"]
        Resource["リソース属性<br>・分類<br>・所有者<br>・機密レベル"]
        Env["環境属性<br>・時刻<br>・IPアドレス<br>・デバイス"]
    end
    User --> Policy
    Resource --> Policy
    Env --> Policy
    Policy["ポリシーエンジン<br>『営業部のマネージャーは<br>営業時間内に社内から<br>顧客データを閲覧可能』"]
    Policy --> Decision{"許可 or 拒否"}

ABACはRBACよりも柔軟で細かい権限制御が可能ですが、実装と管理が複雑になります。

開発者ツールで認証・認可の挙動を確認する

Chrome DevToolsを使って、実際の認証・認可の挙動を確認する方法を解説します。

前提条件

  • Google Chrome(最新版推奨)
  • 検証対象のWebサイト(自分で開発中のサイトまたは学習用のサイト)

Networkタブで認証リクエストを確認する

手順1: DevToolsを開く

Chromeで対象のWebサイトにアクセスし、以下のいずれかの方法でDevToolsを開きます。

  • Windows/Linux: F12またはCtrl + Shift + I
  • Mac: Cmd + Option + I

手順2: Networkタブを選択

DevToolsの上部タブから「Network」を選択します。

手順3: ログインリクエストを確認

ログインフォームでユーザー名とパスワードを入力してログインします。Networkタブに表示されるリクエストの中から、ログインに関するリクエスト(通常はPOSTメソッド)を見つけてクリックします。

確認すべきポイント

  1. Request Headers: 送信されたヘッダー情報
  2. Response Headers: サーバーからのレスポンスヘッダー(Set-Cookieなど)
  3. Payload/Form Data: 送信されたフォームデータ(パスワードがマスクされていることを確認)

Authorizationヘッダーの確認

トークン認証を使用しているサイトでは、APIリクエストにAuthorizationヘッダーが含まれています。

手順1: APIリクエストをフィルタリング

Networkタブの「Filter」欄に「api」や「fetch」と入力するか、「XHR」ボタンをクリックしてAPIリクエストのみを表示します。

手順2: リクエストヘッダーを確認

任意のAPIリクエストをクリックし、「Headers」タブでAuthorizationヘッダーを確認します。

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Applicationタブでトークンの保存場所を確認する

手順1: Applicationタブを開く

DevToolsの上部タブから「Application」を選択します。

手順2: Storage項目を確認

左側のサイドバーから以下の項目を確認できます。

  • Cookies: HttpOnly以外のCookieに保存されたトークン
  • Local Storage: localStorageに保存されたトークン
  • Session Storage: sessionStorageに保存されたトークン

HTTPステータスコードで認証・認可の状態を判断する

Networkタブの「Status」列で、認証・認可に関連するステータスコードを確認できます。

ステータスコード 意味 対処法
200 OK 正常に処理された 問題なし
401 Unauthorized 認証に失敗した ログインが必要、またはトークンが無効/期限切れ
403 Forbidden 認可に失敗した アクセス権限がない
404 Not Found リソースが存在しない URLが正しいか確認(認可失敗を404で隠す場合もある)

実践: Basic認証のヘッダーを確認する

Basic認証が設定されているサイトにアクセスした際の挙動を確認してみましょう。

手順1: Basic認証のサイトにアクセス

Basic認証が設定されているサイトにアクセスすると、ブラウザのダイアログでユーザー名とパスワードの入力を求められます。

手順2: 認証情報を入力

正しいユーザー名とパスワードを入力してログインします。

手順3: Authorizationヘッダーを確認

Networkタブでリクエストを選択し、「Headers」タブで以下のようなヘッダーが含まれていることを確認します。

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

手順4: Base64デコードで検証

DevToolsのConsoleタブで以下のコマンドを実行すると、エンコードされた値をデコードできます。

1
2
atob('dXNlcm5hbWU6cGFzc3dvcmQ=')
// 出力: "username:password"

この結果から、Basic認証では認証情報がBase64でエンコードされているだけで、暗号化されていないことがわかります。これが、Basic認証ではHTTPS通信が必須とされる理由です。

まとめ

この記事では、認証と認可の違いから、代表的な認証方式の比較、開発者ツールでの確認方法まで解説しました。ポイントを振り返りましょう。

認証と認可の違い

  • 認証(Authentication): 「あなたは誰?」を確認するプロセス
  • 認可(Authorization): 「あなたは何ができる?」を確認するプロセス
  • 401エラーは認証の失敗、403エラーは認可の失敗を示す

認証方式の選択

  • Basic認証: 開発環境の簡易的な保護に最適
  • フォーム認証: 一般的なWebアプリケーションに最適
  • トークン認証: SPA、モバイルアプリ、API認証に最適

セキュリティのベストプラクティス

  • すべての認証通信はHTTPS経由で行う
  • トークンは適切な場所に安全に保存する
  • 認可は「拒否がデフォルト」の原則で設計する
  • 認証・認可の失敗は適切にログに記録する

次回は、トークン認証の代表格であるJWT(JSON Web Token)の仕組みと構造について詳しく解説します。

参考リンク