えっまだ知らないの?認証と認可を制覇して安全なウェブサイトを作ろう!

2025年4月28日月曜日

セキュアコーディング

この記事では、ウェブサイトやアプリのセキュリティを守る上でめちゃくちゃ基本的な認証と認可について解説します。

「聞いたことはあるけど、違いがイマイチ…」「どうやって安全に実装すればいいの?」

大丈夫、この記事を読めば、二つの概念の違いからセキュアコーディングにおける役割まで、スッキリ理解できますよ。

正直、これを理解せずにウェブ開発するのは、玄関の鍵を開けっ放しで外出するようなものかもしれません…!

この記事で学べること

  • 認証と認可の基本的な意味と目的がわかる
  • 二つの決定的な違いが図解で理解できる
  • なぜセキュアコーディングで認証と認可が必要なのか理由がわかる
  • 安全な実装のための基本的な考え方が身につく
  • よくあるセキュリティリスクと対策の初歩を知れる

認証とは何か?入り口で「あなたは誰?」を確認する仕組み

まず「認証」からいきましょう。

認証とは、カンタンに言うと「あなたが、あなたが主張する本人であるかを確認する」ための手続きのこと。

ウェブサービスにログインするときの ID とパスワードの入力、あれがまさに認証です。
システムが「お、〇〇さんだね、どうぞ入って!」と確認しているイメージですね。

身近な例でいうと、家のドアを開けるときの「鍵」が認証にあたります。
正しい鍵を持っている人だけが家に入れますよね。

会員制のお店の入り口で「会員証」を見せるのも認証の一種といえるでしょう。

つまり、認証は「アクセスしようとしている人が、本当にその資格のある本人なのか?」を確認する、いわば入り口でのチェックポイントなんです。

+-----------+      +-----------------+      +---------+
|           | ---->|  システム       | ---->|         |
| ユーザー   |      | (ID/パスワード確認)|      | アクセスOK |
| (本人と主張)| ---->|                 | ---->|         |
+-----------+      +-----------------+      +---------+
                   ↑
                認証プロセス

認証の目的は「本人確認」

認証の目的、それはズバリ「なりすましを防ぐこと」です。

悪意のある人が他の誰かになりすましてシステムに侵入しようとするのを防ぐために、本人確認を行うわけですね。

例えば、通販サイトで自分のアカウントにログインするとき、ID とパスワードを入力します。
もし認証がなければ、誰でもあなたのアカウントに入れてしまい、勝手に買い物をしたり、個人情報を見たりできてしまいます。想像するだけで恐ろしいですよね!

だからこそ、「あなたは本当に〇〇さん本人ですか?」と確認する認証が必要不可欠なのです。

Webサービスにおける認証の具体例

普段私たちが使っているウェブサービスには、いろいろな認証方法があります。

一番身近なのは、やっぱりID(ユーザー名やメールアドレス)とパスワードの組み合わせでしょう。

他にも、最近よく見かけるようになった認証方法には、次のようなものがあります。

  • SMS認証
    スマホに送られてくる確認コードを入力するやつ。
  • 生体認証
    指紋や顔で本人確認するやつ。スマホのロック解除でおなじみですね。
  • ソーシャルログイン
    Google や Twitter のアカウントを使ってログインするやつ。
  • 多要素認証 (MFA)
    ID/パスワードに加えて、SMS認証やアプリ生成コードなどを組み合わせる、より強力な認証方法。

どの方法も、「アクセスしようとしている人が正当なユーザー本人であること」を確認するという目的は同じです。

認可とは何か?「あなたは何ができる?」権限を与える仕組み

さて、次は「認可」です。認証が無事に済んだら、次はこの認可の出番。

認可とは、「認証されたユーザーに対して、何をする権限があるかを判断し、許可する」ための仕組みです。

認証が「あなたは誰?」を確認するのに対し、認可は「じゃあ、あなたは何をしていい人?」を確認するプロセスと考えましょう。

身近な例でいうと、ホテルのルームキーがわかりやすいかもしれません。

ルームキー(認証済み)で自分の部屋のドアは開けられますが、他の人の部屋や、関係者以外立ち入り禁止のエリアのドアは開けられませんよね。

その「どのドアを開ける権限があるか」を制御しているのが認可の考え方です。

会社の入館証も、役職や部署によって入れるエリアが制限されていることがありますが、あれも認可の一例です。

+-----------+      +-----------------+      +---------------------+
|           | ---->|                 | ---->| 機能A (アクセスOK)  |
| 認証済み  |      |  システム       |      +---------------------+
| ユーザー   | ---->| (権限チェック)  | ---->| 機能B (アクセス拒否)|
|           |      |                 |      +---------------------+
+-----------+      +-----------------+
                   ↑
                認可プロセス

認可の目的は「権限管理」

認可の目的は、ズバリ「ユーザーができることを適切に制限すること」、つまり権限管理です。
認証で本人確認が済んだとしても、そのユーザーにあらゆる操作を許可してしまうのは危険です。

例えば、ブログサービスを考えてみてください。

一般ユーザーは自分の記事を書いたり編集したりできますが、他の人の記事を勝手に削除したり、サイト全体の設定を変更したりすることはできません。

そうした操作ができるのは、特別な権限を持った管理者ユーザーだけです。

このように、ユーザーの種類や役割に応じて、できること・できないことを細かく制御するのが認可の役割。不必要な操作や情報へのアクセスを防ぎ、システムの安全性を保つのです。

Webサービスにおける認可の具体例

ウェブサービスにおける認可の例も、実は身の回りにたくさんあります。

  • 管理者と一般ユーザーの権限差
    管理画面に入れるのは管理者だけ、というのは典型的な認可。
  • ファイルのアクセス権限
    Google Drive などで、特定のファイルへのアクセスを「閲覧のみ許可」「編集許可」と設定するのも認可です。自分だけが見られるファイル、というのも認可の結果ですね。
  • SNSの公開範囲設定
    投稿を「全体公開」「友達のみ公開」「非公開」と設定するのも、誰に閲覧を許可するかの認可制御。
  • 有料プランと無料プランの機能差
    特定の機能を使えるのが有料プランユーザーのみ、というのも認可による制限。

認証された後、ユーザーがサービス内で具体的に「何ができるか」をコントロールしているのが認可、と覚えておきましょう。

認証と認可の決定的な違いとは?

さあ、ここまでの説明で、認証と認可がそれぞれどんなものか、なんとなく掴めてきたでしょうか?

でも、「やっぱりまだゴチャゴチャになる…」という人もいるかもしれません。
大丈夫! ここで、二つの決定的な違いを整理しておきましょう。ポイントは「誰が(Who)」「何を(What)」です。

  • 認証 (Authentication)
    目的:「あなたは?」を確認する(本人確認)。
    タイミング: 基本的に最初に行われる。
    例: ログイン、会員証提示。
  • 認可 (Authorization)
    目的:「あなたにをする権限があるか?」を判断・許可する(権限管理)。
    タイミング: 認証の後に行われる。
    例: 管理者機能へのアクセス、ファイルの編集権限。

簡単にまとめると、まず「認証」で本人確認をしてドアを開け、次に「認可」でその人が部屋の中で何をしていいかを決める、という流れになります。

この順番は絶対に間違えないようにしましょう! 認証されていない人に権限を与えるなんて、ありえないですからね。

          +-------------------+      +-------------------+
          |      認証         |---->|      認可         |
          | (あなたは誰?)    |      | (あなたは何できる?)|
          +-------------------+      +-------------------+
          ↑                      ↑
      (例: ログイン)          (例: 機能アクセス制御)

認証と認可は連携プレープロセスを理解しよう

実際のシステムでは、認証と認可は密接に連携して動いています。ユーザーがログイン(認証)すると、システムはそのユーザーが誰であるかを特定します。

そして、そのユーザー情報に基づいて、「この人は管理者だから、管理画面へのアクセスを許可しよう」「この人は一般ユーザーだから、記事の投稿は許可するけど、他の人の記事削除は禁止しよう」といった判断(認可)が行われるわけです。

例えば、ECサイトで考えてみましょう。

1. まず、メールアドレスとパスワードでログインします(認証)。
2. ログインに成功すると、マイページにアクセスできます。ここには自分の注文履歴や登録情報が表示されます(認可 - 自分の情報へのアクセス権限)。
3. でも、他のユーザーの注文履歴を見ることはできません(認可 - 他人への情報アクセスは拒否)。

このように、認証された結果を受けて、次に何が許可されるかが決まる。この連携プレーがセキュリティの基本なのです。

これはどっち?認証と認可のよくある勘違い

ここで、よくある勘違いポイントをチェックしてみましょう。
以下の操作は、認証でしょうか? それとも認可でしょうか?

  • ウェブサイトにIDとパスワードでログインする
     → これは「認証」ですね。本人確認のプロセスです。
  • ログイン後、自分のプロフィール情報を編集する
     → これは「認可」です。認証されたユーザーに、自分の情報編集が許可されています。
  • 管理者としてログインし、他のユーザーのアカウントを停止する
     → これも「認可」です。管理者という役割(認証済み)に対して、特別な操作権限が与えられています。
  • 銀行のATMでキャッシュカードを入れて暗証番号を入力する
     → これは「認証」です。カードの持ち主本人かを確認しています。
  • ATMでお金を引き出す
     → これは「認可」です。認証された後、口座残高の範囲内でお金を引き出す操作が許可されています。

どうでしょう?

「何を確認しているのか?」「どのタイミングで行われるのか?」を考えれば、区別しやすくなるはずです。認証は入り口のチェック、認可は入った後の行動制限、と覚えておくと良いでしょう。

なぜ要るの?セキュアコーディングにおける認証と認可

さて、認証と認可の基本的な意味と違いは理解できたと思います。

では、なぜセキュアコーディング、つまり安全なプログラムを作る上で、この二つがこれほどまでに口を酸っぱくして言われるのでしょうか?

答えはシンプル。認証と認可の実装に不備があると、サイバー攻撃の格好の的になり、深刻なセキュリティ事故につながるからです。

想像してみてください。

もし認証がザルだったら? 誰でも簡単になりすまし放題です。

もし認可がガバガバだったら? 一般ユーザーが勝手に管理者権限を手に入れて、システムを破壊したり、全ユーザーの個人情報を抜き取ったりできてしまうかもしれません。

セキュアコーディングの観点では、この認証と認可をいかに堅牢に実装するかが、ウェブサイトやアプリケーションの安全性を左右する、めちゃくちゃ大きな要素なのです。

認証の不備が引き起こす怖いリスク

認証の実装を甘く見ていると、次のような恐ろしいリスクが現実のものとなります。

  • なりすまし・不正ログイン
    弱いパスワードを許可していたり、パスワードの試行回数制限がなかったりすると、ブルートフォース攻撃(総当たり攻撃)や辞書攻撃で簡単にパスワードが破られ、アカウントが乗っ取られる可能性があります。最も基本的な、そして頻発するリスクです。
  • セッションハイジャック
    ログイン状態を管理する仕組み(セッション管理)に不備があると、攻撃者にログイン状態を乗っ取られ、本人になりすまして不正操作される危険があります。
  • 安全でないパスワードリセット
    パスワードを忘れた際の再設定プロセスに脆弱性があると、攻撃者が他人のパスワードを勝手に変更できてしまいます。

認証は、システムへの最初の関門。ここが突破されると、被害は一気に拡大します。

認可の不備が引き起こすもっと怖いリスク

認証を突破された後、あるいは認証自体は正常でも、認可の仕組みに穴があると、さらに深刻な事態を招きます。

  • 権限昇格
    一般ユーザーなのに、何らかの方法で管理者権限などを不正に取得できてしまう脆弱性。システムの根幹を揺るがしかねません。
  • 不適切なアクセス
    本来アクセスできないはずの他人のデータ(個人情報、機密ファイルなど)にアクセスしたり、編集・削除したりできてしまう問題。情報漏洩に直結します。いわゆる「IDOR (Insecure Direct Object References)」もこの一種です。URL の ID を変えたら他人の情報が見えちゃった、なんてケースですね。
  • 機能の不正利用
    一般ユーザーが、管理者向けの機能や、自分には許可されていないはずの機能を実行できてしまうケース。

認可の不備は、攻撃者にとっては「お宝」へのアクセス権を得るようなもの。被害は計り知れません。

安全な認証と認可のためのセキュアコーディング基本原則

では、どうすれば安全な認証・認可を実装できるのでしょうか?
完璧なセキュリティに「絶対」はありませんが、セキュアコーディングの基本原則を守ることで、リスクを大幅に減らすことができます。ここでは、特に意識したい基本的な考え方を紹介します。

  • パスワードは必ずハッシュ化して保存する
    パスワードを生のテキストで保存するのは論外! 必ずハッシュ化という処理をして、元のパスワードがわからない状態にしましょう。ソルトを使うとなお良しです。
  • 多要素認証 (MFA) を検討する
    ID/パスワードだけでなく、SMSコードや認証アプリなどを組み合わせることで、不正ログインのリスクを劇的に下げられます。可能な限り導入を検討しましょう。
  • 最小権限の原則を守る
    ユーザーやプログラムには、その役割を果たすために必要最小限の権限だけを与えるという考え方。これが認可設計の基本中の基本です。
  • アクセス制御は必ずサーバーサイドで行う
    見た目上(フロントエンド)でボタンを隠したりするだけではダメ。必ずサーバー側で、「このユーザーにこの操作を実行する権限があるか?」を毎回チェックするようにしましょう。
  • セッション管理を適切に行う
    ログイン状態を維持するためのセッションIDは、推測困難で、有効期限を設定し、HTTPSで通信するなど、安全に取り扱う必要があります。
  • フレームワークのセキュリティ機能を活用する
    多くのウェブフレームワーク(Ruby on Rails, Laravel, Django など)には、認証・認可のための仕組みが用意されています。自前で実装するよりも、これらの実績ある機能を適切に利用する方が安全な場合が多いでしょう。

これらの原則を意識して設計・実装することが、セキュアコーディングの第一歩です。

【要注意】認証と認可でよく狙われる脆弱性とその対策

最後に、認証・認可の不備に関連して、攻撃者によく狙われる代表的な脆弱性とその対策の方向性に触れておきましょう。

  • 不適切なアクセス制御 (Broken Access Control)
    認可の不備全般を指します。権限昇格や IDOR などが含まれます。対策の基本は、やはりサーバーサイドでの厳密な権限チェックと、最小権限の原則の徹底です。
  • 認証の失敗 (Identification and Authentication Failures)
    弱いパスワードポリシー、不適切なセッション管理、MFA の欠如などが原因で発生します。パスワードポリシーの強化、MFA の導入、安全なセッション管理の実装が対策となります。OWASP Top 10 でも常に上位に挙げられる項目です。
  • セッション固定攻撃 (Session Fixation)
    攻撃者が用意したセッションIDをユーザーに使わせることで、ログイン後にそのユーザーになりすます攻撃。ログイン成功時にセッションIDを新しく発行し直すことで対策できます。
  • ブルートフォース攻撃・辞書攻撃
    パスワードを力ずくで試す攻撃。アカウントロックアウト機能(一定回数失敗したら一時的にログイン不可にする)や、CAPTCHAの導入、MFAが有効な対策です。

これらの脆弱性について、さらに詳しく知りたい場合は、「OWASP Top 10」などのキーワードで調べてみると、より深い情報が見つかりますよ。


認証と認可の基本的な実装例

さて、認証と認可の概念や要点がわかったところで、「じゃあ、実際にどうやってプログラムで実現するの?」と気になりますよね。

ここでは、特定のプログラミング言語に偏らず、認証と認可がプログラム上でどのように処理されるか、その基本的な流れと考え方を、簡単な疑似コードを交えて紹介します。

あくまで考え方のイメージをつかんでもらうためのものなので、細かい部分は実際の言語やフレームワークによって異なりますよ!

シンプルなログイン認証の例 (考え方)

まずは、一番基本となる「ログイン認証」の流れを見てみましょう。ユーザーがIDとパスワードを入力してログインボタンを押した、という場面を想像してください。

  1. ユーザーからの入力受け取り
    プログラムは、まずユーザーが入力したID(例: メールアドレス)とパスワードを受け取ります。
  2. ユーザー情報の検索
    受け取ったIDをもとに、データベースなどから該当するユーザーの情報を探します。ユーザーが見つからない場合は、この時点で「IDまたはパスワードが違います」と判断できますね。
  3. パスワードの比較
    ユーザーが見つかったら、次はそのユーザー情報に保存されている「ハッシュ化されたパスワード」を取り出します。
    そして、今回ユーザーが入力した生のパスワードを、保存されているハッシュ値と同じ方法でハッシュ化します。
    この二つのハッシュ値を比較して、一致するかどうかを確認します。生のパスワード同士を比較するわけではない点に注意してください!
  4. 認証結果の判断
    ハッシュ値が一致すれば、パスワードも正しいと判断でき、認証成功です! ログイン後のページに進めるようにします。
    一致しなければ、認証失敗。「IDまたはパスワードが違います」とユーザーに伝えます。

パスワード比較部分のイメージを疑似コードで書くと、こんな感じです。

// ユーザーが入力したパスワード
input_password = "ユーザーが入力したパスワード"

// DBから取得した、ユーザー登録時にハッシュ化して保存しておいたパスワードハッシュ
stored_password_hash = "データベースに保存されているハッシュ値"

// 入力されたパスワードを、保存時と同じ方法でハッシュ化する
input_password_hash = hash_function(input_password) // hash_functionはハッシュ化処理の例

// 二つのハッシュ値を比較する
if (input_password_hash == stored_password_hash) {
  // 認証成功!
  print("ログイン成功!ようこそ!")
} else {
  // 認証失敗!
  print("IDまたはパスワードが違います。")
}

これが、最も基本的なパスワード認証の流れと考え方です。実際には、これに加えてセッション管理などの処理が必要になります。

基本的なアクセス認可の例 (考え方)

次に、認証されたユーザーが、特定の機能(例えば、管理者専用ページ)にアクセスしようとしたときの「認可」の流れを見てみましょう。

  1. リクエストの受け付け
    認証済みのユーザーが、管理者専用ページへのアクセスをリクエストします。プログラムは、まず「どのユーザーが」リクエストしているかを把握します(通常、セッション情報などから判断します)。
  2. ユーザーの役割(権限)情報の取得
    リクエストしてきたユーザーが、どのような役割(例: 管理者、一般ユーザー、ゲストなど)を持っているかを、データベースなどから取得します。ユーザーごとに役割や権限レベルが設定されていることが前提です。
  3. 必要な権限との照合
    アクセスしようとしている機能(管理者専用ページ)には、どのような権限が必要かを調べます(例: 「管理者」ロールが必要)。
    そして、ユーザーが持っている役割が必要な権限を満たしているかを確認します。
  4. アクセス許可/拒否の判断
    ユーザーが必要な権限を持っていれば、アクセスを許可し、管理者専用ページを表示します。
    権限がなければ、アクセスを拒否し、「アクセス権限がありません」といったメッセージを表示したり、別のページにリダイレクトしたりします。

権限チェック部分のイメージを疑似コードで書くと、こんな具合です。

// 現在ログインしているユーザーの情報 (認証時に取得済み)
current_user = get_current_user() // ユーザー情報を取得する関数の例

// ユーザーの役割(ロール)を取得 (例: "admin", "general", "guest")
user_role = current_user.role

// アクセスしようとしている機能に必要な権限
required_role = "admin" // この機能には管理者権限が必要

// ユーザーの役割が必要な権限を満たしているかチェック
if (user_role == required_role) {
  // 認可OK! アクセス許可
  print("管理者ページへようこそ!")
  // ここで管理者ページを表示する処理
} else {
  // 認可NG! アクセス拒否
  print("このページへのアクセス権限がありません。")
  // エラーページを表示するか、他のページへ誘導する処理
}

サーバーサイドで必ずこのチェックを行うことが、セキュアな認可のキモとなります。見た目だけでボタンを隠しても、URLを直接叩かれたら意味がないですからね。

フレームワーク利用のすすめ

ここまで認証と認可の基本的な実装の流れを疑似コードで示しましたが、「うーん、なんだか自分で全部作るのは大変そうだし、セキュリティ的に大丈夫か心配…」と感じた人もいるかもしれません。

その感覚、正しいです!

実際のウェブ開発では、これらの認証・認可の仕組みを自前で一から実装することは少なく、多くの場合、ウェブアプリケーションフレームワークが提供する機能を活用します

例えば、以下のようなフレームワークには、認証・認可のための便利な仕組みが組み込まれていることが多いです。

  • Ruby on Rails (Devise, CanCanCan など)
  • PHP / Laravel (標準機能, Jetstream など)
  • Python / Django (標準の認証システム)
  • Node.js / Express (Passport.js など)

これらのフレームワークを利用するメリットは大きいです。

  • セキュリティ対策が考慮されている
    実績のあるライブラリや機能は、よく知られた脆弱性への対策が施されていることが多い。
  • 実装の手間が省ける
    面倒な定型処理を自分で書かなくて済む。
  • コミュニティによるサポート
    多くの開発者に使われているため、情報やノウハウを見つけやすい。

もちろん、フレームワークの機能を「ただ使う」だけでなく、その仕組みや設定の意味をきちんと理解して使うことが重要です。

ですが、車輪の再発明を避け、安全で効率的な開発を進めるために、フレームワークの活用は非常に有効な手段と言えるでしょう。

【まとめ】認証と認可をマスターしてセキュアな開発者へ

お疲れ様でした!
今回は、セキュアコーディングの超基本である「認証」と「認可」について、その違いから要点まで解説してきました。
もう一度、ポイントをおさらいしておきましょう。

  • 認証は「あなたは誰?」を確認する本人確認プロセス。
  • 認可は「あなたは何ができる?」を制御する権限管理プロセス。
  • 認証が先、認可が後。二つは連携してシステムの安全を守る。
  • 実装に不備があると、なりすましや不正アクセス、情報漏洩など深刻なリスクがある。
  • 安全な実装には、パスワードのハッシュ化、最小権限の原則、サーバーサイドでのチェックなどが欠かせない。

認証と認可は、地味に見えるかもしれませんが、ユーザーとシステムを守るための土台となる部分です。

今回学んだ知識をベースに、ぜひご自身の開発に活かしてみてください。
まずは、お使いのフレームワークが提供している認証・認可の仕組みについて調べてみるのも良いステップです。

セキュアコーディングの世界は奥が深いですが、一つ一つ理解を深めていけば、必ず安全なサービスを作れるようになります。

このブログを検索

  • ()

自己紹介

自分の写真
リモートワークでエンジニア兼Webディレクターとして活動しています。プログラミングやAIなど、日々の業務や学びの中で得た知識や気づきをわかりやすく発信し、これからITスキルを身につけたい人にも役立つ情報をお届けします。 note → https://note.com/yurufuri X → https://x.com/mnao111

QooQ