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 Unauthorizedと403 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認証のリクエストヘッダーは以下のようになります。
|
|
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"}トークン認証のリクエストヘッダーは以下のようになります。
|
|
トークン認証のメリット
- ステートレス:サーバー側でセッション情報を保持する必要がない
- スケーラビリティ:ロードバランサー配下の複数サーバーで認証情報を共有しやすい
- クロスドメイン対応:異なるドメイン間でも認証情報を共有可能
- モバイルアプリとの相性が良い
トークン認証のデメリット
- トークンの安全な保存場所の検討が必要
- トークンの失効処理が複雑(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メソッド)を見つけてクリックします。
確認すべきポイント
- Request Headers: 送信されたヘッダー情報
- Response Headers: サーバーからのレスポンスヘッダー(
Set-Cookieなど) - 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タブで以下のコマンドを実行すると、エンコードされた値をデコードできます。
|
|
この結果から、Basic認証では認証情報がBase64でエンコードされているだけで、暗号化されていないことがわかります。これが、Basic認証ではHTTPS通信が必須とされる理由です。
まとめ
この記事では、認証と認可の違いから、代表的な認証方式の比較、開発者ツールでの確認方法まで解説しました。ポイントを振り返りましょう。
認証と認可の違い
- 認証(Authentication): 「あなたは誰?」を確認するプロセス
- 認可(Authorization): 「あなたは何ができる?」を確認するプロセス
- 401エラーは認証の失敗、403エラーは認可の失敗を示す
認証方式の選択
- Basic認証: 開発環境の簡易的な保護に最適
- フォーム認証: 一般的なWebアプリケーションに最適
- トークン認証: SPA、モバイルアプリ、API認証に最適
セキュリティのベストプラクティス
- すべての認証通信はHTTPS経由で行う
- トークンは適切な場所に安全に保存する
- 認可は「拒否がデフォルト」の原則で設計する
- 認証・認可の失敗は適切にログに記録する
次回は、トークン認証の代表格であるJWT(JSON Web Token)の仕組みと構造について詳しく解説します。