認証と認可 — 誰が何をできるかを管理する仕組み
バイブコーディング入門 — 第16回
前回のおさらいと、今回のテーマ
前回(第15回)では、JSONを正面から取り上げた。6つのデータ型、入れ子構造の読み方、よくある文法ミス5つ、そしてバリデーション(検証)の方法。JSONが読めるようになったことで、APIのレスポンスが暗号ではなく普通の文章に見えるようになった。
さて、ここまでの連載で「Webアプリの仕組み」をかなり理解できるようになった。URI、HTTP、REST API、JSON。あなたはもう、AIが書いたコードの構造を読み解く力を持っている。
しかし、1つ大きなテーマが残っている。ログイン機能だ。
あなたが30人の人材紹介会社の管理職だとしよう。社内で使う候補者管理アプリをバイブコーディングで作った。候補者の名前、連絡先、面接記録、年収情報が入っている。このアプリにログイン機能がなかったら、URLを知っている人は誰でも全データにアクセスできてしまう。取引先にURLが漏れたら、候補者の年収情報まで見られてしまう。
ログイン機能の裏側で動いているのが、今回のテーマ「認証」と「認可」だ。
認証(にんしょう)は「あなたは誰ですか?」の確認。認可(にんか)は「あなたは何をしていいですか?」の確認。この2つは似ているようで、まったく違う概念だ。
今回学ぶこと:
- 認証と認可の違い(なぜ両方必要なのか)
- パスワード認証の仕組み(パスワードはどう保存されるのか)
- OAuth(オーオース)の仕組み(Googleアカウントでログインできる理由)
- JWT(ジェイダブリューティー)の仕組み(ログイン状態を維持するトークン)
- バイブコーディングでAIにログイン機能を依頼するテンプレート
第11回で学んだCookieとセッションの知識が、ここで一気につながる。
認証と認可の違い — ホテルのたとえで理解する
認証と認可を、ホテルにたとえてみよう。
あなたがホテルにチェックインする場面を想像してほしい。
フロントで身分証を見せる。これが認証だ。「この人は予約した田中太郎さん本人である」と確認すること。
フロントでルームキーを受け取る。このキーで開けられるのは503号室だけだ。スイートルームのドアは開かない。従業員専用のバックヤードにも入れない。これが認可だ。「田中太郎さんは503号室にだけ入れる」という権限の管理。
Webアプリに置き換えてみよう。
認証の例:
- ログイン画面でメールアドレスとパスワードを入力する
- Googleアカウントでログインボタンを押す
- スマートフォンに届いた6桁のコードを入力する
認可の例:
- 一般社員は自分の担当案件だけ見える。マネージャーはチーム全員の案件が見える
- 経理部門だけが売上データをダウンロードできる
- 管理者だけがユーザーを追加・削除できる
認証が先で、認可が後。この順番は絶対だ。「誰だかわからない人に権限を渡す」ことはありえない。
バイブコーディングでアプリを作るとき、「ログイン機能をつけて」とだけAIに伝えると、認証だけ実装されて認可が抜け落ちることがある。「ログイン機能をつけて、さらに役割ごとにアクセスできる画面を分けて」と伝えれば、認証と認可の両方が実装される。
パスワード認証の仕組み — パスワードはそのまま保存されない
もっとも基本的な認証方式が、パスワード認証だ。メールアドレスとパスワードを入力してログインする、おなじみの方式。
ここで1つ、意外に知られていない事実がある。あなたのパスワードは、サーバーにそのまま保存されていない。
「え、じゃあどうやって照合しているの?」と思うかもしれない。
答えは「ハッシュ化」だ。ハッシュ化とは、元のデータを一方通行で別の文字列に変換することだ。
たとえば、パスワードが mypassword123 だとする。これをハッシュ化すると、こんな文字列になる。
$2b$10$N9qo8uLOickgx2ZMRZoMye.IjqXbOW5LYmFm1C6cGnMhKPnUq2HBG
この変換は一方通行だ。ハッシュ化された文字列から元のパスワードに戻すことはできない。
ログイン時の流れはこうなる。
- あなたがパスワードを入力する
- サーバーがそのパスワードをハッシュ化する
- データベースに保存されているハッシュ値と比較する
- 一致すれば「本人」と判断する
なぜわざわざこんなことをするのか。理由は明確だ。万が一データベースが流出しても、パスワードそのものは漏れない。ハッシュ値からは元のパスワードに戻せないので、攻撃者がデータベースを盗んでも、すぐにはログインできない。
バイブコーディングでログイン機能を作るとき、AIは通常このハッシュ化を自動で実装してくれる。しかし、「パスワードがどう保存されているか」を知っておくと、セキュリティに関する判断ができるようになる。たとえば、サービスから「あなたのパスワードはXXXXです」というメールが届いたら、そのサービスはパスワードをそのまま保存している可能性がある。それは危険なサービスだ。
セッションとトークン — ログイン状態をどう維持するか
ログインに成功した後、どうやって「ログイン中」の状態を維持するのか。ここで第11回の知識がつながる。
第11回で学んだ通り、HTTPはステートレス(状態を持たない)だ。サーバーは「さっきログインした人」と「初めてアクセスした人」を区別できない。そこで、ログイン成功後に「通行証」を発行する。
通行証の渡し方には、大きく2つの方式がある。
方式1: セッション方式(サーバー側で管理)
ログインに成功すると、サーバーが「セッションID」という通行証を発行する。この通行証の番号だけをCookieに入れてブラウザに渡す。通行証の中身(誰がログインしているか、いつまで有効か)はサーバー側に保存する。
たとえるなら、映画館の半券だ。半券にはチケット番号だけが書いてある。座席情報や料金は映画館のシステムに記録されている。
方式2: トークン方式(クライアント側で管理)
ログインに成功すると、サーバーが「トークン」という通行証を発行する。この通行証には「誰がログインしているか」「いつまで有効か」「どの権限を持っているか」の情報がすべて書き込まれている。サーバーはこの情報を保存しない。
たとえるなら、パスポートだ。パスポートには本人の情報がすべて記載されている。入国審査官はパスポートを見るだけで判断できる。どこかのデータベースに問い合わせる必要がない。
どちらの方式が良いかは、アプリの規模と用途による。小規模なアプリならセッション方式で十分だ。複数のサービスを連携させる大規模なシステムでは、トークン方式が使われることが多い。
バイブコーディングでSupabase(スーパーベース)というサービスを使う場合は、トークン方式が採用されている。AIに「Supabaseの認証機能を使ってログインを実装して」と伝えれば、トークン方式で実装してくれる。
OAuth(オーオース)— Googleアカウントでログインできる理由
Webサービスのログイン画面で「Googleでログイン」「LINEでログイン」というボタンを見たことがあるだろう。あのボタンの裏側で動いているのが OAuth(オーオース)だ。正式名称は「OAuth 2.0」で、他のサービスのアカウント情報を借りて本人確認をする仕組みだ。
なぜOAuthが生まれたのか。理由は2つある。
1つ目: ユーザーの手間を減らすため。新しいサービスを使うたびに、メールアドレスとパスワードを登録するのは面倒だ。すでに持っているGoogleアカウントやLINEアカウントでログインできれば、登録の手間がなくなる。
2つ目: パスワード管理のリスクを減らすため。サービスごとにパスワードを設定すると、同じパスワードを使い回しがちだ。1つのサービスからパスワードが流出すると、他のサービスにも被害が広がる。OAuthを使えば、パスワードを預ける先をGoogle等の大手に限定できる。
OAuthの流れを、具体的に追ってみよう。あなたが「タスク管理アプリ」に「Googleでログイン」ボタンを押した場合。
- タスク管理アプリが、Googleに「この人の本人確認をお願いします」とリクエストを送る
- 画面がGoogleのログインページに切り替わる
- あなたがGoogleアカウントのパスワードを入力する(パスワードはGoogleにだけ送られる。タスク管理アプリには送られない)
- Googleが「この人は確かに田中太郎です」という証明書(認可コード)をタスク管理アプリに渡す
- タスク管理アプリがその証明書をGoogleに提示して、アクセストークン(通行証)を受け取る
- ログイン完了。以降はこのアクセストークンを使って通信する
ここで重要なのは、手順3だ。パスワードはGoogleにだけ送られる。タスク管理アプリはパスワードを知ることがない。これがOAuthの最大のメリットだ。
「でも、タスク管理アプリにGoogleのデータを全部見られるのでは?」という不安があるかもしれない。心配はいらない。OAuthでは「何の情報を共有するか」を細かく指定できる。たとえば「名前とメールアドレスだけ」「Googleカレンダーの読み取りだけ」のように、必要最小限の情報だけを許可する。Googleのログイン画面で「このアプリが以下の情報にアクセスします」という確認画面が出るのは、このためだ。
JWT(ジェイダブリューティー)— 通行証の中身を読む
OAuthやトークン認証で発行される「トークン」の代表的な形式が、JWT(ジェイダブリューティー)だ。正式名称は JSON Web Token(ジェイソン・ウェブ・トークン)。名前の通り、前回学んだJSONがベースになっている。
JWTは、見た目がこんな文字列だ。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Iu田中太郎IiwiYWRtaW4iOmZhbHNlfQ.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
一見すると暗号のように見えるが、実は3つのパートがドット(.)で区切られている。
パート1: ヘッダー(どの方式で署名したか) パート2: ペイロード(中身。誰の通行証か、いつまで有効か、どの権限か) パート3: 署名(改ざんされていないことの証明)
前回のJSON知識を使って、パート2(ペイロード)を読んでみよう。このパートは単にBase64(ベースロクジュウヨン)という方式でエンコード(変換)されているだけだ。デコード(元に戻す)すると、こうなる。
{
"sub": "user_12345",
"name": "田中太郎",
"role": "manager",
"exp": 1744905600
}
これは前回学んだJSONそのものだ。
- sub: ユーザーID(誰の通行証か)
- name: ユーザー名
- role: 権限(manager = マネージャー権限)
- exp: 有効期限(数字はUNIXタイムスタンプという形式で、2025年4月16日のような日時を表す)
ここで気づいてほしいことがある。JWTのペイロードには「認証」の情報(この通行証はuser_12345のもの)と「認可」の情報(roleがmanager)の両方が入っている。サーバーはこのJWTを受け取るだけで、「誰で」「何ができるか」を判断できる。データベースに問い合わせる必要がない。
ただし、JWTのペイロードは暗号化されていない。Base64でエンコードされているだけなので、誰でも中身を読める。だからJWTにパスワードやクレジットカード番号を入れてはいけない。パート3の署名があるので「改ざん」はできないが、「閲覧」はできる。ここが重要なポイントだ。
多要素認証(MFA)— パスワードだけでは足りない時代
ここまでパスワード認証、OAuth、JWTを見てきた。しかし、現代のWebセキュリティでは「パスワードだけでは不十分」という考え方が主流になっている。
多要素認証(たようそにんしょう)、英語ではMFA(Multi-Factor Authentication)という仕組みがある。「2段階認証」という呼び方のほうが聞き覚えがあるかもしれない。
認証に使える要素は、大きく3種類ある。
- 知識: パスワード、PINコード、秘密の質問(あなたが知っていること)
- 所持: スマートフォン、セキュリティキー、ICカード(あなたが持っているもの)
- 生体: 指紋、顔、虹彩(あなた自身の体の特徴)
多要素認証は、このうち2つ以上を組み合わせる。たとえば「パスワード(知識)+ スマートフォンに届く6桁コード(所持)」の組み合わせ。パスワードが漏れても、スマートフォンを持っていなければログインできない。
バイブコーディングでアプリを作るとき、社内の機密データを扱うなら多要素認証の導入を検討する価値がある。Supabaseでは、メール認証に加えて、TOTP(タイムベースのワンタイムパスワード。Google Authenticator等で表示される6桁の数字)に対応している。
よくある不安と答え
OAuthで外部サービスにデータを全部見られるのか
見られない。OAuthでは「スコープ」という仕組みで、共有する情報の範囲を限定する。「名前とメールアドレスだけ」「カレンダーの読み取りだけ」のように、必要最小限だけを許可する。ログイン画面で表示される確認ダイアログに、どの情報を共有するかが書いてある。
パスワードを忘れたとき「パスワードの再設定」しかできないのはなぜか
パスワードがハッシュ化されて保存されているからだ。サービス側もあなたの元のパスワードを知らない。だから「パスワードを教える」ことはできず、「新しいパスワードを設定してもらう」しかない。パスワードリセットのメールが届く方式は、メールアドレスの所有者であることの確認(認証)も兼ねている。
JWTの有効期限が切れたらどうなるのか
アクセスが拒否される。一般的なアプリでは、有効期限が短いアクセストークン(15分〜1時間)と、有効期限が長いリフレッシュトークン(数日〜数週間)の2種類を使う。アクセストークンが切れたら、リフレッシュトークンを使って新しいアクセストークンを自動で取得する。ユーザーが頻繁にログインし直す必要がないのは、この仕組みのおかげだ。
自社アプリにログイン機能は必須なのか
社外に公開しない社内ツールでも、複数人が使うならログイン機能は付けたほうがよい。「誰が何をしたか」のログ(操作記録)を残せるし、退職者のアカウントを無効にすることもできる。1人だけで使う個人ツールなら、ログイン機能は不要な場合もある。
バイブコーディングで認証機能を頼むテンプレート
バイブコーディングでAIにログイン機能を依頼するとき、次のテンプレートが使える。
テンプレート: 認証・認可機能の実装依頼
「このアプリにログイン機能を追加したい。
認証方式:
- メールアドレスとパスワードによるログイン
- Googleアカウントでのログイン(OAuth)
- パスワードリセット機能
認可(権限管理):
- 管理者(admin): すべての機能にアクセス可能。ユーザーの追加・削除ができる
- マネージャー(manager): チーム全員のデータを閲覧・編集できる。ユーザー管理はできない
- 一般ユーザー(member): 自分のデータだけ閲覧・編集できる
技術的な要件:
- Supabaseの認証機能を使うこと
- パスワードは必ずハッシュ化して保存すること
- ログイン画面、新規登録画面、パスワードリセット画面を作ること
- ログインしていない場合はログイン画面にリダイレクトすること
- 権限のない画面にアクセスした場合は403エラー画面を表示すること
まずデータベースのテーブル設計をJSONで見せてほしい。OKが出たら実装に入って。」
このテンプレートのポイントは3つある。
1つ目: 認証と認可を明確に分けて指示している。「ログイン機能をつけて」だけでは認可が抜ける。
2つ目: 権限の種類と、各権限でできることを具体的に書いている。admin、manager、memberの3段階で、それぞれの操作範囲が明確だ。
3つ目: 「まずデータベース設計をJSONで見せて」と段階を分けている。第13回のリソース設計、第15回のJSON知識を活かして、実装前にデータ構造を確認できる。
認証まわりのセキュリティで知っておくべきこと
バイブコーディングでAIがログイン機能を実装してくれたとしても、以下の3点は自分でチェックしておきたい。
1点目: パスワードの最低要件を設けているか。8文字以上、英数字混合など、短すぎるパスワードを拒否する仕組みがあるか。
2点目: ログイン失敗時のメッセージが具体的すぎないか。「メールアドレスが存在しません」と表示すると、攻撃者に「このメールアドレスは登録されていない」という情報を与えてしまう。「メールアドレスまたはパスワードが正しくありません」のように、どちらが間違っているかを特定できないメッセージが望ましい。
3点目: ログイン試行回数の制限があるか。パスワードを何回でも試せる状態だと、総当たり攻撃(ブルートフォースアタック)のリスクがある。5回失敗したら一定時間ロックする、といった制限を設けるのが一般的だ。
これらのチェックポイントをAIに伝えるには、こう依頼すればよい。「パスワードは8文字以上・英数字混合を必須にして。ログイン失敗メッセージはメールアドレスとパスワードのどちらが間違いかを特定できないようにして。5回連続で失敗したら15分間ロックして」。
まとめ
認証(あなたは誰?)と認可(あなたは何をしていい?)は、ログイン機能の両輪だ。パスワードはハッシュ化されて保存され、元に戻すことはできない。OAuth(オーオース)は、GoogleやLINEのアカウントを借りて本人確認する仕組みで、パスワードを預ける先を限定できる。JWT(ジェイダブリューティー)は、ユーザー情報と権限を1つのトークンに詰め込んだ通行証で、中身はJSONだ。バイブコーディングでログイン機能を依頼するときは、認証と認可を分けて具体的に指示することが、安全なアプリを作る第一歩になる。
次回は「HTTPS・セキュリティの基本 — 知らなかったでは済まない」。通信の暗号化、XSS、SQLインジェクションなど、バイブコーダーが最低限知っておくべきセキュリティの基礎を解説する。
参考リファレンス
- 前回: 第15回「JSON完全理解 — データ形式の文法とバリデーション」(/articles/vc-015)
- 次回: 第17回「HTTPS・セキュリティの基本 — 知らなかったでは済まない」(/articles/vc-017)
- 第11回「ステートレスとCookie/セッション — ログイン状態の正体」(/articles/vc-011)
- 第13回「リソース設計の実践 — AIに伝わるデータ構造の考え方」(/articles/vc-013)
- バイブコーディング入門 カリキュラム(/vibe-coding)




