Skip to main content

認証と認可 — 誰かを確かめることと、何を許すこと

「認証」と「認可」はどちらも英語の頭が Auth で始まり、日本語でも一字違いです。混ざったまま設計すると、ログインさえしていれば何でもできるシステムが生まれます。

2 つを分ける基準は単純です。誰であるかを確かめるのが認証、何を許すかを決めるのが認可。

この章で学ぶこと

  • 認証と認可の違いと、必ず認証が先に来る理由
  • 失敗したときに返すべきステータスコードの違い
  • 認証状態をセッションで持つかトークンで持つか
  • 認可をどこで判定すべきか
前提知識

HTTP のステータスコードの分類を前提にします。

この章で扱わないこと

実装の詳細と、データベース設計の観点は既存のガイドが扱います。

観点参照先
テーブル設計、パスワード保管、MFA、監査ログデータベース設計ガイド — 認証・認可システムの設計
外部サービスとの認証連携データベース設計ガイド — OAuth と OpenID Connect
SPA でのトークン保管とセッションReact ガイド — SPA の認証
フレームワークでの実装Laravel API 開発ガイド — 認証 / 認可

認証と認可

認証 (Authentication)認可 (Authorization)
問いあなたは誰ですかそれをしてよいですか
確かめるもの本人性権限
ログイン、指紋、ワンタイムパスワード管理者だけが削除できる、自分の注文だけ見られる
失敗時401 Unauthorized403 Forbidden
順序

順序が逆になることはありません。誰か分からない相手に何を許すかは決められないからです。

例外に見えるのが匿名アクセスです。ログインせずに公開ページを見られるサイトでは認証が省かれているように見えますが、実際には「匿名という身元」で認可を判定しています。「匿名でも閲覧は許す」という認可のルールが働いています。

ステータスコードの使い分け

紛らわしいのは 401 の名前です。Unauthorized (認可されていない) と書いてあるのに、意味は認証されていないです。仕様上の命名の歴史的な事情で、実際の使い分けは次のとおりです。ステータスコード全体の分類は HTTP で扱っています。

コード状況クライアントが取るべき行動
401 Unauthorized資格情報が無い、期限切れ、不正ログインし直す
403 Forbidden認証は通ったが権限が足りないあきらめる。やり直しても同じ

**401 は「やり直せば通るかもしれない」、403 は「やり直しても通らない」。**この対比で覚えると迷いません。

認証の 3 要素

本人性を確かめる材料は、大きく 3 種類に分かれます。

要素内容弱点
知識 (Something you know)本人だけが知っていることパスワード、暗証番号漏れる、推測される、使い回される
所持 (Something you have)本人だけが持っているものスマートフォン、ハードウェアキー盗まれる、紛失する
生体 (Something you are)本人の身体的特徴指紋、顔、虹彩変更できない、誤認識がある

多要素認証 (MFA) は、異なる要素を 2 つ以上組み合わせることを指します。ここが誤解されやすい点で、「パスワード + 秘密の質問」はどちらも知識なので多要素ではありません。両方とも同じ漏洩経路でまとめて破られるためです。

「パスワード + スマートフォンへのコード送信」なら知識と所持なので多要素です。パスワードが漏れても、端末が手元に無ければ突破できません。

認証状態をどう持ち回るか

HTTP はステートレスなので、一度ログインしても次のリクエストでは「誰だか分からない」状態に戻ります。認証済みであることを毎回のリクエストで示す必要があります。

セッション方式トークン方式
何を渡すかセッション ID (意味を持たない文字列)署名付きトークン (中に情報が入る)
状態の置き場サーバー側 (セッションストア)トークン自体
失効させるセッションストアから消せば即座有効期限まで止められない
サーバー間の共有ストアの共有が要る署名鍵さえあれば検証できる
主な運搬手段クッキーAuthorization ヘッダー、またはクッキー

判断の軸は失効の即時性とスケールのどちらを優先するかです。

セッション方式は、サーバーが状態を持つぶん即座に失効させられます。「不正利用が疑われるアカウントを今すぐ止める」が確実にできます。

トークン方式は、サーバーが状態を持たないので水平にスケールしやすくなります。代わりに、いったん発行したトークンは有効期限が来るまで有効です。**この期限は瞬間で表します。**地方時で持つと、解釈するタイムゾーン次第で期限が動きます (日時とタイムゾーン)。これを緩和するために、短命なアクセストークンと長命なリフレッシュトークンを組み合わせ、失効リストを別途持つ設計が使われます。

認可のモデル

権限をどう表現するかにはいくつかの型があります。

モデル考え方向いている場面
RBAC (ロールベース)ユーザーにロールを与え、ロールに権限を紐づける組織の役職と権限が対応する場合
ABAC (属性ベース)ユーザー・リソース・状況の属性から判定する「自分の部署のものだけ」など文脈が要る場合
ACL (アクセス制御リスト)リソースごとに誰が何をできるかを列挙するファイル共有のように個別指定が要る場合

実務では組み合わせることが多くなります。「管理者ロールなら全件、一般ユーザーなら自分のものだけ」は RBAC と ABAC の混在です。

認可はサーバーで判定する

画面にボタンを表示しないことは認可ではありません。

// これは認可ではない。見た目を整えているだけ
{user.role === 'admin' && <DeleteButton />}

ボタンを隠しても、API を直接叩けば実行できます。ブラウザの開発者ツールでリクエストを組み立てるのは誰にでもできます。認可の判定は必ずサーバー側で行い、クライアント側の出し分けは体験を良くするための補助と位置づけます。

OWASP Top 10:2025 で A01 が Broken Access Control (アクセス制御の不備) であることは、この失敗が今も最も多いことを示しています。典型的な形は次のとおりです。

  • URL の ID を書き換えると他人のデータが見える (/orders/1001/orders/1002 に変える)
  • 管理用 API に認可チェックが入っていない
  • クライアント側だけで権限を判定している

1 つ目は特に頻出で、リソースの所有者と操作者が一致するかをサーバーで必ず確認する必要があります。

記述で答えるときの骨子

認証と認可はどう違うのか、と問われたときの組み立て方です。

  1. それぞれの定義を 1 文で — 認証は本人性の確認、認可は権限の判定
  2. 順序を述べる — 認証が先で認可が後。誰か分からない相手に権限は決められない
  3. 具体例を 1 組 — 「社員証で入館するのが認証、入れる部屋が役職で決まるのが認可」のように、身近な対比を使う
  4. 技術的な現れ方に触れる — 失敗時のステータスコードが 401403 で分かれる
  5. 実装上の注意を 1 つ — 認可はサーバー側で判定する。画面での出し分けは認可ではない

3 番目の具体例があると、定義の暗記ではなく理解として伝わります。1 から 3 までで基本は満たせるので、時間や字数が限られるならそこまでで区切ります。

よくある誤解

401 は権限が無いという意味」401 は認証されていない状態です。権限不足は 403 です。名前が Unauthorized なので紛らわしいのですが、実際の使い分けは認証と認可で分かれます。

「パスワードと秘密の質問で多要素認証」 — どちらも知識の要素なので多要素ではありません。異なる要素を組み合わせる必要があります。

「ログインできているなら認可も済んでいる」 — 別です。ログインは「誰か」を確定させただけで、その人に何を許すかは別途判定します。

「管理者にしかボタンを表示していないので安全」 — 表示の制御は認可ではありません。API を直接叩かれれば通ります。

「JWT を使えばログアウトも即座に効く」 — トークン方式は有効期限まで止められないのが原則です。即座に止めたいなら失効リストなどの仕組みを別途用意します。

確認問題

問 1. 次の処理は認証と認可のどちらですか。
A. ワンタイムパスワードの照合
B. 「この注文は自分のものか」の確認
C. パスワードのハッシュ値の照合
D. 「管理者ロールを持っているか」の確認
E. 指紋の読み取り

答え:

分類理由
A認証所持の要素で本人性を確かめている
B認可誰かは既に分かっていて、そのリソースへの権限を判定している
C認証知識の要素で本人性を確かめている
D認可権限の判定
E認証生体の要素で本人性を確かめている

判別の問いは「本人かどうかを調べているか、してよいかを調べているか」です。A・C・E は身元の確認、B・D はその後の権限判定です。

B は見落とされやすい認可です。「ログインしているから自分の注文だ」と決めつけると、ID を書き換えて他人の注文が見える不備になります。

問 2. API が 403 Forbidden を返しました。クライアントはログイン画面へ遷移させるべきですか。

答え: させるべきではありません。

403 は「あなたが誰かは分かっているが、それをする権限が無い」という意味です。ログインし直しても同じユーザーなら結果は変わりません。ログイン画面へ飛ばすと、ユーザーは何度ログインしても同じエラーに遭遇します。

正しい対応は、権限が無い旨を伝えて別の導線を出すことです。

コード対応
401ログイン画面へ。トークンの更新を試みる
403「権限がありません」と表示。管理者への申請導線があれば案内する

逆に、トークンの期限切れで 403 を返している API があると、クライアントは再ログインすべき状況を判別できません。サーバー側でこの 2 つを正しく返し分けることが前提になります。

問 3. 面接で「認証と認可はどう違いますか」と聞かれました。3 文で答えてください。

解答例:

認証は「その人が本人であるか」を確かめる処理で、パスワードや生体情報などで身元を確定させます。認可は「その人にその操作を許すか」を判定する処理で、ロールや所有関係をもとに権限を決めます。認証が先で認可が後という順序があり、誰か分からない相手に何を許すかは決められないためです。

要素の対応は次のとおりです。

含めた要素
1 文目認証の定義 + 手段の例
2 文目認可の定義 + 判定材料の例
3 文目順序 + その理由

余裕があれば「失敗時は認証が 401、認可が 403」を足すと、技術的な理解まで示せます。逆に**定義だけを 2 文並べて終わると、暗記との区別が付きません。**順序とその理由が入っているかが分かれ目です。

まとめ

  • 認証は「誰であるか」の確認、認可は「何を許すか」の判定です
  • 認証が先で認可が後。順序が逆になることはありません
  • 失敗時は認証が 401、認可が 403401 はやり直せば通るかもしれない、403 はやり直しても通らない、という違いです
  • 認証の要素は知識・所持・生体の 3 つ。多要素認証は異なる要素の組み合わせで、同じ要素を 2 つ重ねても多要素ではありません
  • セッション方式は即座に失効させられ、トークン方式はスケールしやすい。トークンは有効期限まで止められないのが原則です
  • **認可はサーバー側で判定します。**画面での出し分けは認可ではありません
  • OWASP Top 10:2025 の A01 は Broken Access Control です
関連リファレンス

次に読む