📑 この章の目次
title: 認証・認可 icon: 🔑 card_desc: 誰がアクセスしてよいかを決める仕組み — 認証と認可の違い・セッション/JWT・OAuth・MFA slug: 05-auth
05 認証・認可 — 「誰か」と「何をしてよいか」を区別する作法
「ログイン機能を作って」——この一言に、「本人確認(認証)」と「権限確認(認可)」という2つの全く別の問題が隠れています。この章では、現場で一番混同されやすいこの2つを、根本から区別できるようにします。
一言でいうと
認証(Authentication)は「あなたは誰か」を確認すること。認可(Authorization)は「あなたは何をしてよいか」を判断すること。この2つはセットで語られますが、別の問題です。ログイン画面でパスワードを入力するのは認証、ログイン後に「他人の注文履歴は見えない」になっているのは認可。認可を抜きにすると、誰もが管理者になれてしまいます。
1. なぜ認証・認可が必要なのか
まず、これがない世界を想像してください。
GET /api/users/123/orders ← 誰が頼んだリクエストか分からない
このAPIに認証・認可がないと、何が起きるか:
- URLの
123を124に書き換えるだけで、他人の注文履歴が見える(認可の欠如) - 「管理者用」のAPIを、誰でも叩けてしまう(権限チェックなし)
- リクエストの送り主が誰か一切分からない(認証の欠落)
これらは悪意がなくても起きる事故です。「自分のデータを見ようとしたら、URLの打ち間違いで他人のデータが見えた」という設計ミスは、現実によくあります。
⚠ 通称: IDOR(アイディーオーアール/Insecure Direct Object Reference)。URLのIDを書き換えるだけで他人データにアクセスできる脆弱性。認可チェック忘れの代表例。
認証・認可は、「使い勝手」のためでなく「安全」のための仕組みです。後回しにされがちですが、最初から設計に組み込むのが作法です(→ 後述)。
2. 🔑 「認証」と「認可」の区別
ここが本章の核心です。この2つを混同するのが、初学者が一番よく陥る罠です。
認証(Authentication)= 誰か
「あなたは誰ですか?」を確認すること。代表的な手段:
- パスワード(知っていること)
- ワンタイムパスコード(持っていること)
- 指紋・顔(生体情報)
認証が成功すると、システムは「この利用者はユーザーID=123の山田さんだ」と身元を特定します。
認可(Authorization)= 何をしてよいか
「山田さんは、何をしてよいか」を判断すること。身元が分かった上で、さらに:
- この注文を見てよいか(自分の注文か、他人の注文か)
- ユーザーを削除してよいか(管理者権限があるか)
- 記事を編集してよいか(編集権限があるか)
💡 権限の管理には「役割(管理者・一般等)で分ける」方式(RBAC: 役割ベースアクセス制御)等がよく使われます。いずれにせよ「誰が・何をしてよいか」をルール化しておくのが認可です。
例えていうと: ホテルのカードキー
フロントで身分証を提示してチェックインするのが認証。「あなたは201号室の山田様ですね」と身元を確認します。
部屋のカードキーで201号室のドアを開けるのが認可。201号室には入れるが、他人の部屋(202号室)のカードキーは使えない。これが「自分のリソースにはアクセスできる・他人のにはできない」という認可の構造です。
| 認証(Authentication) | 認可(Authorization) | |
|---|---|---|
| 質問 | 誰ですか? | 何をしてよいか? |
| タイミング | ログイン時 | ログイン後の毎操作 |
| 例 | パスワード確認 | 「自分の注文か」「管理者か」 |
| 失敗例 | 「パスワードが違います」 | 「このページは閲覧権限がありません」 |
💡 頭文字の A が同じなので混同しやすいのが難点です。Authentication(認証)と Authorization(認可)。英語圏でも略すと両方「Auth」になるため、文脈で読み分けます。
3. セッション・Cookie方式 —— ブラウザ型の古典
「毎回パスワードを入力する」のは現実的ではありません。ログイン状態を維持する仕組みが必要です。その1つがセッション方式です。
仕組み
1. ログイン(ID + パスワード送信)
↓
2. サーバーが「この人はログイン中」と記憶(セッション生成)
↓
3. サーバーが「セッションID」をCookieでブラウザに渡す
↓
4. 以降のリクエストにはCookieが自動送信される
↓
5. サーバーはセッションIDを見て「誰か」を特定
- Cookie(クッキー): ブラウザに保存される小さなデータ。リクエストのたび自動でサーバーに送信される
- セッション: サーバー側が「このセッションID=誰」を記憶している状態
メリットとデメリット
| メリット | デメリット |
|---|---|
| ブラウザがCookieを自動送信で楽 | 状態をサーバーが記憶(複数台構成でセッション共有の工夫が要る) |
| サーバー側でセッションを即座に無効化できる(ログアウト確実) | モバイルアプリ・他サービス連携に不向き |
| 歴史が長く実績豊富 | CSRFの対策が別途必要(後述) |
💡 「ステートフル」(状態あり)な方式。サーバーが「誰がログイン中か」を覚えているのが特徴。そのためログアウトはサーバー側でセッションを消せば確実(Cookieを消すだけでは不十分)。API(ステートレス指向)とは相性が良くない面があります(→ 第3章 REST の「ステートレス」参照)。
4. トークン方式 JWT —— API・モバイル向き
セッション方式の「サーバーが状態を記憶する」という負担を減らすため、トークン方式が登場しました。代表が JWT(ジェイダブリューティー/通称「ジョット」/JSON Web Token)です。
トークンとは
ログイン成功時、サーバーはトークン(入場券のような文字列)を発行します。以降、クライアントはリクエストのたびこのトークンを添えて送ります。サーバーはトークンを見て「誰か」「権限」を判断します。
JWT の特徴
JWT は、署名付きの JSON データです。中身は大きく3部構成:
ヘッダ.ペイロード.署名
- ペイロード: 「誰か」「権限」「有効期限」などの情報(JSON)
- 署名: サーバーだけが持つ鍵で作った改ざん検知用のハンコ
💡 ペイロードは誰でも読めます(Base64でエンコードされているだけ・暗号化ではない)。重要なのは「署名があることで改ざんを検知できる」点。鍵を持たない攻撃者は、署名付きの正しいトークンを作れません。
メリットとデメリット
| メリット | デメリット |
|---|---|
| サーバーが状態を記憶しなくてよい(ステートレス) | 発行後の無効化が難しい(有効期限が切れるまで有効) |
| モバイル・他サービス連携に向く | ペイロードは読めるので機密情報を入れてはいけない |
| 複数台構成でスケールしやすい | 扱いを間違えると重大な脆弱性になる(→ 後述) |
💡 無効化の工夫: JWTは「発行したら期限まで有効」が基本ですが、実運用では「短命のアクセストークン+長命のリフレッシュトークン」の2段構えにし、リフレッシュトークンをサーバー側で無効化できるようにする等の工夫がよく使われます。
⚠ JWTの落とし穴: 「署名検証をしない」「alg: none攻撃を許す」「機密情報をペイロードに入れる」等の実装ミスが、深刻な認証バイパスにつながります。ライブラリを正しく使い、検証は必ず行います。
5. OAuth / OpenID Connect —— 「Googleでログイン」の正体
「Googleでログイン」「GitHubでログイン」を見たことがあるでしょう。これの正体が OAuth(オース/通称「オーオース」も/OAuth 2.0)と、その上に乗る OpenID Connect(オープンアイディー・コネクト/OIDC)です。
OAuth は「委譲」
OAuth の核心は委譲(いじょう)——「あなたの代わりに、限られたことだけ、外部のサービスに許可する」仕組みです。
例: あなたが「写真印刷サービス」にGoogleフォトの写真へのアクセスを許可する。
- 写真印刷サービスにパスワードを渡すわけではない(これが重要)
- 「写真を読む権限だけ」を、一時的・限定的に許可する
- いつでも取り消せる
あなた → Google: 「写真印刷サービスに写真を読む権限を渡して」
Google → 写真印刷サービス: 「写真を読むためのアクセストークン」を発行
写真印刷サービス → GoogleフォトAPI: トークンを使って写真を取得
OpenID Connect は「認証」
OAuth(委譲=認可)の上に、「この人はGoogleアカウントの誰か」という認証の仕組みを乗せたのが OIDC。「Googleでログイン」のボタンを押すと、Googleが「この人はこの人です」と**保証(IDトークン発行)**してくれます。
| OAuth 2.0 | OpenID Connect | |
|---|---|---|
| 役割 | 認可(委譲: 限られた権限を貸す) | 認証(この人は誰か) |
| よく使う場面 | 「アプリに〇〇へのアクセスを許可」 | 「Googleでログイン」 |
| 関係 | 基盤(下回り) | OAuth の上に認証を乗せたもの |
⚠ 「外部に任せて安心」ではない: OIDC を使う側は、受け取ったIDトークンの署名と内容(発行者・有効期限・宛先等)を必ず検証します。検証をサボると、偽のIDトークンで成りすまされる事故に繋がります。「成熟した基盤に任せる」選択は有効ですが、検証の責任は使う側にある点に注意。
6. 多要素認証 MFA —— 「1つの鍵」に頼らない
パスワードだけだと、1つ漏れただけで侵入されるリスクがあります。これを減らすのが多要素認証(MFA/エムエフエー)です。
認証の3要素
MFA は、以下の異なる性質の要素を組み合わせます:
| 要素 | 例 | 特徴 |
|---|---|---|
| 知識(知っていること) | パスワード・暗証番号 | 忘れたら困る・他人に教えうる |
| 所有(持っていること) | スマホ(SMS/アプリ)・セキュリティキー | 物理的に必要・なくすと困る |
| 生体(本人であること) | 指紋・顔・虹彩 | 忘れない・なくさないが変更不可 |
💡 「所有」の代表格としてパスキー(FIDO2 / WebAuthn 等の技術)が近年広がっています。パスワードをなくし、フィッシング(偽サイト騙し)に強いのが特徴。注目される「パスワードレス」の方向です。
「パスワード(知識)+ スマホのワンタイムコード(所有)」のように、異なる性質を2つ以上組み合わせるのが MFA の基本。「同じ性質」を2つ(例: パスワード+もう一つパスワード)は、同一要素の重複で MFA の意味が薄れます。
💡 2FA(ツーエフエー/二要素認証)は MFA の「2つ組み合わせ」版。現場では 2FA / MFA ほぼ同義で使われます。
なぜ効果的か
パスワードが漏洩しても、**スマホ(所有)**がなければログインできません。攻撃者は「パスワードを知っている」だけでなく「物理的にスマホも手に入れる」必要があり、難易度が跳ね上がります。
7. よくある落とし穴と、なぜ「作法」なのか
❌ やってはいけないこと
| 落とし穴 | 何が起きるか | 正しい対応 |
|---|---|---|
| パスワードを平文で保存 | DB漏洩ですべてバレる | ハッシュ化(bcrypt等の専用アルゴリズム)して保存(→ 第4章) |
| 認可チェックを忘れる(IDOR) | 他人データが見える | 「自分のリソースか・権限があるか」を毎操作で確認 |
| トークンをlocalStorage等に無防備に置く | XSS(スクリプト注入)で盗まれる | 保管場所を吟味(HttpOnly Cookie 等・用途で判断) |
| HTTPSを使わない | 通信を盗聴されてトークン・パスワード漏洩 | 本番は必ずHTTPS(→ 第4章: 暗号化通信) |
| JWTの署名検証をしない | 任意のトークンで成りすませる | ライブラリを正しく使い必ず検証 |
| 権限を「フロントだけ」で隠す | APIを直接叩かれると突破される | サーバー側で必ず認可チェック(フロントの隠蔽はUX用) |
| CSRF対策をしない(Cookie方式) | 悪意あるサイトから勝手にリクエスト送られる | SameSite属性・CSRFトークン等で対策 |
| ログイン試行を無制限に許す | ブルートフォース(総当たり)で破られる | 試行回数制限・ロック(→ 第3章: レート制限) |
✅ 認証・認可の設計の作法
- 認証と認可を明確に分ける —— 「誰か」と「何をしてよいか」は別のレイヤー
- 認可チェックはサーバー側で毎回 —— フロントのUI制御だけでは不十分
- パスワードは絶対ハッシュ化(
bcrypt等・生保存・可逆復元しない) - HTTPSを必須にする(本番での平文通信は論外)
- MFAで「1つの鍵」に頼らない(知識+所有等の組み合わせ)
- 成熟した基盤(OIDC等)の活用を検討(自作リスクの回避・ただし検証は必須)
- ブルートフォース対策(試行回数制限・ロック)を忘れない
💡 CSRF(シーエスアールエフ/Cross-Site Request Forgery/「偽造リクエスト」): ユーザーがログイン中に、悪意ある別サイトが「勝手にリクエストを送る」攻撃。Cookieが自動送信される仕組みを悪用するため、Cookie方式では特に注意が必要です。
面接・実務での意味
「認証と認可の違い、説明できますか?」
この質問は、「安全な設計ができるか」を問う一番手軽な検査です。「同じだろ」と答える人は、IDOR等の認可不備を作りがちです。逆に「認証は誰か・認可は何をしてよいか」と即答でき、さらに「認可チェックはサーバー側で毎回必須」と言える人は、現場で信頼されます。
まとめ
- 認証(Authentication)は「誰か」・認可(Authorization)は「何をしてよいか」。別の問題として分けて設計する
- セッション・Cookie はブラウザ型の古典(ステートフル・ログアウト確実)・JWT はAPI向き(ステートレス・署名付き・無効化は工夫が要る)
- OAuth は委譲(限られた権限を貸す)・OIDC はその上の認証(「Googleでログイン」の正体・検証は必須)
- MFA は知識・所有・生体の異なる性質を組み合わせて「1つの鍵」に頼らない(パスキー等でパスワードレスも)
- 認可チェックはサーバー側で毎回必須・パスワードはハッシュ化・HTTPS必須・CSRF/ブルートフォース対策も忘れずに
💡 次のステップ: 誰がアクセスしてよいかの「認証・認可」が見えました。次は、開発現場で「環境を丸ごと運ぶ」もう一つの基盤技術——**コンテナ(Docker)**を扱います。第6章では、開発環境と本番環境の差異をなくす作法を学びます。