認証と認可
認証と認可とは
- 認証(Authentication) = あなたは誰? を確認すること(ログイン)
- 認可(Authorization) = あなたに何を許可するか? を決めること(権限)
似た言葉ですが役割はまったく別物です。「認証は身分証の確認、認可は入室許可」と例えられます。
混同するとこう壊れる
初学者が最初に踏む地雷は、ログインできた人なら何をしてもよいと扱ってしまう実装です。
注文詳細ページの URL が /orders/1234 だとします。ログイン中の利用者が数字を 1235 に書き換えたとき、他人の注文が表示されてしまう — 「ログイン済みかどうか」しか見ていないと必ず起きる事故です。認証は通っている(本物の利用者ではある)のに、認可が抜けている状態です。正しくは「ログイン済みか」に加えて「その注文はこの利用者のものか」まで毎回確認します。
この種の欠陥は、画面を普通に操作している限り再現しないのが厄介なところです。自分の注文しか一覧に出てこないからです。URL やリクエストの中身は利用者が自由に書き換えられる前提で、サーバー側の判定を点検してください。
ログインの前後で起きていること
「認証」と一口に言っても、実際には次の段階に分かれています。個々の技術がどこを担当しているのかを意識すると、仕組みの位置づけが一気に見通せます。
- 識別 — 誰だと名乗ったか(メールアドレスなど)
- 認証 — その名乗りが本物かを確かめる(パスワードの照合、追加要素の確認)
- 状態の維持 — [[HTTP]] はリクエストごとに記憶を持たないため、「ログイン中」を別の仕組みで覚える
- 認可 — 個々の操作について、許可してよいかを判定する
- 記録 — 誰がいつ何をしたかを残す([[ログ設計]])
見落としやすいのは、3 と 4 がリクエストのたびに繰り返されることです。ログイン時に一度チェックすれば終わり、ではありません。
初学者向けポイント
- パスワードはハッシュ化して保存する(平文保存は重大事故のもと)
- ログイン状態の維持には セッション(Cookie) か トークン(JWTなど) を使う
- すべての通信は [[HTTPS・TLS]] が前提。トークンが盗まれれば本人になりすませてしまう
よく出る仕組み
| 仕組み | 概要 |
|---|---|
| セッションCookie | サーバーがセッションIDを発行しCookieで管理。伝統的で堅実 |
| JWT | 署名付きトークンに情報を埋め込む。[[REST API]] と相性がよい |
| OAuth 2.0 | 「Googleでログイン」のような権限の委譲の標準 |
| 多要素認証(MFA) | パスワード+確認コードなど複数要素で認証を強化 |
認可の3つの考え方
認可の判定基準は、大きく次の3種類に整理できます。
| 考え方 | 判定の基準 | 例 |
|---|---|---|
| 所有者チェック | 対象データの持ち主かどうか | 「この注文は本人のものか」 |
| ロールベース(RBAC) | 割り当てられた役割 | 「管理者ロールなら削除できる」 |
| 属性ベース(ABAC) | 利用者・対象・状況の属性の組み合わせ | 「同じ部署で、かつ勤務時間内なら」 |
最初は所有者チェックとロールベースの2つで十分です。属性ベースは柔軟ですが、条件が増えるほど「なぜこの人に許可が出たのか」を後から説明しにくくなります。ロールも同じで、例外対応のたびに新しいロールを足していくと、利用者数とほぼ同じ数のロールが並ぶ状態に行き着きます。ロールが人単位に近づいてきたら設計を見直す合図です。
設計の基本原則
- 最小権限の原則: 必要最低限の権限だけを与える
- 認可チェックはサーバー側で必ず行う(フロントの表示制御だけでは守れない)
ここから先の読み進め方
認証と認可は入口が広く、どこから手を付けるか迷いやすい領域です。目的別に4つの群へ整理しました。
本人確認を固める
「本当に本人か」を強くする段階です。サーバー側の守りが [[パスワードの保存とハッシュ化]]、利用者側の守りが [[多要素認証]] で、この2つは補完関係にあります。両者の土台になる「戻せない変換」と「戻せる変換」の違いは [[暗号化の基礎]] で整理できます。
ログイン状態を運ぶ
認証そのものは一瞬ですが、その結果は以降のすべてのリクエストで参照されます。サーバー側に状態を置くのが [[セッション管理]]、トークン自体に情報を持たせるのが [[JWT]] で、即時ログアウトのしやすさとスケールしやすさのトレードオフになります。自前でパスワードを預からず外部のログインに委ねるなら、[[OAuth・OIDC]] が標準の入口です。
権限を設計する
「誰に何を許すか」を具体的なルールへ落とす段階です。判断の指針が [[最小権限の原則]]、クラウド上での代表的な実装が [[AWS IAM]]、データベースの行単位まで踏み込んだ形が [[Row Level Security(RLS)]] です。アプリのコードではなくDB側で強制できると、認可の書き忘れが構造的に起きにくくなります。
運用で守り続ける
権限と認証情報は、与えた瞬間から古びていきます。有効期限を短くして漏えい時の被害を抑えるのが [[短期クレデンシャル]]、「社内ネットワークだから安全」という前提を捨てる設計思想が [[ゼロトラスト]] です。認証処理を各サービスに散らさず入口で一括処理する構成は [[APIゲートウェイ]]、認証機能そのものを外部に任せる選択肢は [[BaaS(Backend as a Service)]] にまとまっています。
関連技術とのつながり
- [[HTTPS・TLS]] — 認証情報を安全に運ぶ土台
- [[REST API]] — トークンによるAPI保護の主戦場
- [[Webセキュリティ]] — 認証まわりは攻撃の主要ターゲット
Q: ログイン中の利用者がURLの `/orders/1234` を `1235` に書き換えると他人の注文が見えてしまう。抜けているのはどれ?
- [ ] 認証(本人かどうかの確認)
- [x] 認可(その操作を許してよいかの判定)
- [ ] 通信の暗号化
解説: 本物の利用者としてログインできている以上、認証は通っています。「その注文はこの利用者のものか」という認可の確認が抜けている状態です。
Q: 認証したあとに「ログイン中」を覚える仕組みが必要になる理由はどれ?
- [ ] パスワードをハッシュ化すると元に戻せなくなるから
- [x] HTTPがリクエストごとに記憶を持たないから
- [ ] ロールベースの認可では役割を保存できないから
解説: HTTPは各リクエストが独立しているため、セッションやトークンで認証結果を持ち回る必要があります。
Q: 「この注文は本人のものか」を確かめる認可の考え方はどれ?
- [x] 所有者チェック
- [ ] ロールベース(RBAC)
- [ ] 属性ベース(ABAC)
解説: 対象データの持ち主かどうかで判定するのが所有者チェックです。ロールベースは割り当てられた役割、属性ベースは利用者や状況の属性の組み合わせで判定します。