← inaro.devAI駆動開発 学習ツール

認証と認可の違い

なぜ学ぶか: 「ログインできる」と「その操作をしてよい」は別問題。この2つ(認証と認可)の混同が、「ログインさえすれば他人の投稿も消せる」ような権限バグを生みます。AIは認証(ログイン)は作れても、認可(権限チェック)を忘れがち。両者の区別が、地味だが重大な脆弱性を防ぎます。

認証(Authentication)=あなたは誰?

ログインで「本人であること」を確認する段階です。

認可(Authorization)=それをしてよい?

「この人はこの操作をする権限があるか」を確認する段階。ログイン済みでも、他人のデータは触れないのが正しい状態です。

定番バグ:認証だけで認可がない

「ログインしていれば誰でも、どの投稿でも削除できる」— 認証は通っても認可が抜けた状態。実際によくある穴です。

サーバー側で「本人か」を確認

削除・更新の前に「この投稿の持ち主は本当にこのユーザーか」をサーバーで確認します。RLSはこれをDBレベルで担保する仕組みです。

コード例

// 投稿を削除する Server Action
"use server";

export async function deletePost(postId: string) {
  // 認証: いま操作している本人を「サーバー側で」確認する
  // (ユーザーIDを引数で受け取ってはいけない。クライアントは偽装できるため)
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) throw new Error("ログインが必要です");

  const post = await getPost(postId);

  // 認可: 「本人の投稿か」の確認 ← これを忘れると他人の投稿も消せる
  if (post.userId !== user.id) {
    throw new Error("この投稿を削除する権限がありません");
  }

  await removePost(postId);
}

確認ポイントは2つ。①「誰か」は必ずサーバー側で取得する — ユーザーIDを引数(クライアントからの入力)で受け取ると偽装できてしまう。②認可チェック(post.userId !== user.id)が抜けると、ログインさえすれば他人の投稿を消し放題。AIが生成した削除・更新処理では、この2点を必ず確認しましょう。

ステップ 1 / 2

※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。