Claude Codeで認証/認可を実装する実践ガイド|Better Auth・Clerk・Supabase Auth・RBAC設計・ミドルウェア保護

【Oracle】不要なインデックスを見つけて削除する方法|パフォーマンス改善の第一歩 AI開発

認証/認可はすべてのWebアプリケーションに必須でありながら、実装ミスがセキュリティ事故に直結する「間違えられない」領域です。Claude Codeを使えば、認証ライブラリのセットアップ、RBAC設計、ミドルウェアでの認可チェック、セキュリティベストプラクティスの適用を正確かつ高速に行えます。

この記事では、2026年時点の主要な認証ソリューション——Better Auth・Clerk・Supabase Auth——をClaude Codeで実装する具体的な手順を解説します。Auth.js v5からBetter Authへの移行背景、RBAC設計、ミドルウェア保護、Supabase RLS(Row Level Security)まで、CLAUDE.md設定テンプレート付きで紹介します。

スポンサーリンク

Better Auth vs Clerk vs Supabase Auth ── 選択基準

2025年9月、Auth.js(NextAuth)の開発チームがBetter Authチームに合流しました。Auth.js v5は長期ベータのまま安定版に至らず、新規プロジェクトにはBetter Authが推奨されています。

項目 Better Auth Clerk Supabase Auth
種別 OSS(自前ホスト) SaaS SaaS + OSS
料金 無料(MAU無制限) $0〜$20+/月(50K MAU無料) $0〜$20+/月(50K MAU無料)
DB 必須(Prisma/Drizzle等) 不要(Clerk管理) Supabase内蔵
プリビルトUI プラグインで提供 完全なUIコンポーネント 自作が必要
RBAC プラグイン Organization + Metadata RLS(Row Level Security)
ベンダーロック なし 中程度 中程度
Claude Code連携 OSSのためコード生成が自由 公式MCP Server提供 MCP Server提供
選択の目安:データ完全所有+最大カスタマイズ→Better Auth、最速実装+プリビルトUI→Clerk、PostgreSQL統合+RLS認可→Supabase Auth

CLAUDE.mdに認証/認可ルールを記述する

CLAUDE.md(認証・認可ルール)
## 認証・認可ルール

### セキュリティ基本方針
- パスワードはbcrypt(saltRounds: 12以上)でハッシュ化
- セッションIDは認証成功後に必ず再生成
- Cookie設定: httpOnly=true, secure=true, sameSite="lax"
- JWTの秘密鍵は環境変数で管理(ソースコードにハードコード禁止)

### 認可チェック(CVE-2025-29927対策)
- ミドルウェアだけでなく、Server Component / API Route内でも二重チェック
  (Next.jsミドルウェアバイパス脆弱性の教訓)
- RBACロール: admin, editor, viewer の3段階
- 機密操作(削除・設定変更)はadminロール必須

### 禁止事項
- ハードコードされたシークレット
- エラーメッセージに内部情報を含めない("パスワードが違います"ではなく"認証に失敗しました")
- ユーザー入力は必ずサニタイズ
- SQLインジェクション: パラメータ化クエリ必須
CVE-2025-29927: Next.jsのx-middleware-subrequestヘッダーを使ったミドルウェアバイパス脆弱性が報告されました。認可チェックはミドルウェアだけに頼らず、Server Component / API Route内でも必ず二重チェックしてください。

Better Auth ── Auth.jsの後継で認証を実装する

Better AuthはTypeScriptネイティブの認証フレームワークで、Auth.jsチームが合流したことで事実上の後継になりました。DB必須ですが、Prisma/Drizzle/Kyselyなどの主要ORMにすべて対応しています。

Better Auth セットアッププロンプト
Better Auth + Prisma + Next.js 16 のセットアップをしてください。

要件:
- メール/パスワード認証
- Google/GitHub OAuth
- JWTセッション
- RBACロール(admin, editor, viewer)
- PrismaスキーマにUser/Session/Account/Verificationモデル追加
- ミドルウェアでの認可チェック(二重チェック)
lib/auth.ts(Better Auth設定)
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { prisma } from "@/lib/prisma";

export const auth = betterAuth({
  database: prismaAdapter(prisma, { provider: "postgresql" }),
  emailAndPassword: { enabled: true },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    },
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    },
  },
  plugins: [nextCookies()],
});
lib/auth-client.ts(クライアント側)
import { createAuthClient } from "better-auth/react";

export const { signIn, signUp, signOut, useSession } = createAuthClient({});
app/api/auth/[…all]/route.ts
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

export const { GET, POST } = toNextJsHandler(auth);
Server Componentでのセッション取得
import { auth } from "@/lib/auth";
import { headers } from "next/headers";

export default async function DashboardPage() {
  const session = await auth.api.getSession({
    headers: await headers(),
  });

  if (!session) {
    redirect("/login");
  }

  return <div>ようこそ、{session.user.name}さん</div>;
}

Clerk ── 最速でプリビルトUIの認証を組み込む

Clerkはプリビルトの認証UI(サインイン/サインアップフォーム、ユーザーメニュー等)を提供するSaaSで、最小限のコードで認証を実装できます。Claude Code向けの公式MCPサーバーも提供しています。

Clerk MCP Server の設定
# Claude CodeにClerk MCPを追加
claude mcp add clerk --transport http https://mcp.clerk.com/mcp

# → Claude CodeがClerkのSDKスニペットを正確に取得できるようになる
Clerk セットアッププロンプト
Clerk + Next.js 16 でサインイン/サインアップを実装してください。

要件:
- ClerkProvider でアプリ全体をラップ
- /sign-in, /sign-up にClerkのプリビルトUIを配置
- middleware.ts でClerk認証ミドルウェアを設定
- 公開ルート: /, /about, /pricing
- 保護ルート: /dashboard以下すべて
- RBACはpublicMetadataでロール管理(admin/member)
middleware.ts(Clerkミドルウェア)
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";

const isPublicRoute = createRouteMatcher(["/", "/about", "/pricing", "/sign-in(.*)", "/sign-up(.*)"]);

export default clerkMiddleware(async (auth, req) => {
  if (!isPublicRoute(req)) {
    await auth.protect();
  }
});

export const config = {
  matcher: ["/((?!_next|[^?]*\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)"],
};
ClerkのRBAC(publicMetadata)
// ミドルウェアでのロールチェック
export default clerkMiddleware(async (auth, req) => {
  if (req.nextUrl.pathname.startsWith("/admin")) {
    const session = await auth();
    const role = session.sessionClaims?.metadata?.role;
    if (role !== "admin") {
      return NextResponse.redirect(new URL("/", req.url));
    }
  }
});

// Server Componentでのロールチェック(二重チェック)
import { currentUser } from "@clerk/nextjs/server";

export default async function AdminPage() {
  const user = await currentUser();
  if (user?.publicMetadata?.role !== "admin") {
    redirect("/");
  }
  return <div>管理画面</div>;
}

Supabase Auth ── RLSで行レベルの認可を実現する

Supabase AuthはPostgreSQLのRLS(Row Level Security)と統合されており、データベースレベルで「誰がどのデータにアクセスできるか」を制御できます。

Supabase Auth セットアッププロンプト
Supabase Auth + Next.js 16 SSR でセットアップしてください。

要件:
- @supabase/ssr を使用(@supabase/auth-helpersは非推奨)
- createBrowserClient(クライアント)とcreateServerClient(サーバー)の2種
- proxy.ts でAuth tokenリフレッシュ(Server Componentsはcookie書き込み不可のため)
- profilesテーブルにRLSポリシー(自分のデータのみ読み書き可)
RLSポリシー(Claude Codeが生成)
-- テーブルにRLS有効化
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

-- SELECT: 自分のデータのみ
CREATE POLICY "ユーザーは自分のプロフィールのみ閲覧可能"
ON profiles FOR SELECT
USING ( (SELECT auth.uid()) = user_id );

-- INSERT: 自分のデータのみ作成
CREATE POLICY "ユーザーは自分のプロフィールのみ作成可能"
ON profiles FOR INSERT TO authenticated
WITH CHECK ( (SELECT auth.uid()) = user_id );

-- UPDATE: 自分のデータのみ更新
CREATE POLICY "ユーザーは自分のプロフィールのみ更新可能"
ON profiles FOR UPDATE TO authenticated
USING ( (SELECT auth.uid()) = user_id )
WITH CHECK ( (SELECT auth.uid()) = user_id );

-- マルチテナント: JWTのteam_id情報で制御
CREATE POLICY "チームメンバーのみアクセス可能"
ON team_data FOR ALL TO authenticated
USING ( team_id IN (
  SELECT (auth.jwt() -> ''app_metadata'' ->> ''teams'')::uuid[]
));
RLSはデータベースレベルで認可を強制するため、APIコードにチェック漏れがあってもデータ漏洩を防げます。ミドルウェア+APIコード+RLSの3重防御が最も安全です。

RBAC(Role-Based Access Control)をClaude Codeに設計させる

RBAC設計プロンプト
以下のWebアプリケーションのRBACロール設計を行ってください。

アプリ概要: チームコラボレーションツール
ユーザー種別:
- admin: 全操作可能(メンバー管理、請求管理)
- editor: コンテンツの作成・編集・削除
- viewer: 閲覧のみ

設計してほしいもの:
1. ロールと権限のマトリックス表
2. DBスキーマ(Prisma)のUser.roleカラム設計
3. 認可チェックのユーティリティ関数
4. Next.js proxy.ts でのルートベース認可
5. Server Component内での二重チェックパターン
認可ユーティリティ(Claude Codeが生成)
// lib/permissions.ts
type Role = "admin" | "editor" | "viewer";
type Permission = "read" | "create" | "update" | "delete" | "manage_users" | "manage_billing";

const rolePermissions: Record<Role, Permission[]> = {
  admin: ["read", "create", "update", "delete", "manage_users", "manage_billing"],
  editor: ["read", "create", "update", "delete"],
  viewer: ["read"],
};

export function hasPermission(role: Role, permission: Permission): boolean {
  return rolePermissions[role]?.includes(permission) ?? false;
}

export function requirePermission(role: Role | undefined, permission: Permission): void {
  if (!role || !hasPermission(role, permission)) {
    throw new Error("権限がありません");
  }
}
Server Componentでの二重チェック
// app/admin/users/page.tsx
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { requirePermission } from "@/lib/permissions";
import { redirect } from "next/navigation";

export default async function AdminUsersPage() {
  const session = await auth.api.getSession({ headers: await headers() });

  if (!session) redirect("/login");

  // ミドルウェアに加えてServer Component内でも権限チェック(二重チェック)
  try {
    requirePermission(session.user.role, "manage_users");
  } catch {
    redirect("/");
  }

  // ... admin only content
}
認可チェックは「ミドルウェア」と「Server Component / API Route」の2箇所で行うのが鉄則です。ミドルウェアだけに頼ると、バイパス脆弱性(CVE-2025-29927)で突破されるリスクがあります。

よくある質問

QAuth.js(NextAuth)はもう使わないほうがいいですか?
AAuth.jsは保守モード(セキュリティパッチのみ)に入っており、新規プロジェクトにはBetter Authが推奨されています。2025年9月にAuth.jsの開発チームがBetter Authチームに合流したため、Better Authが事実上の後継です。既存のAuth.jsプロジェクトは引き続き動作しますが、新機能の追加は期待できません。
QBetter AuthとClerkのどちらを選ぶべきですか?
Aデータを自社で完全に管理したい場合はBetter Auth(OSS、DB自前)、とにかく早く実装して認証UIも任せたい場合はClerk(SaaS、プリビルトUI)です。Clerkは月50,000 MAUまで無料で、公式MCPサーバーもあるためClaude Codeとの連携が楽です。Better Authは無料でMAU無制限ですが、DB構築とUI実装が必要です。
QSupabase AuthのRLSは本当に安全ですか?
ARLSはPostgreSQLのネイティブ機能でデータベースエンジンが直接強制するため、APIコードにバグがあってもデータ漏洩を防げます。ただし、RLSポリシーの記述ミス(USING句の条件漏れ等)があると機能しません。Claude Codeに「このRLSポリシーにセキュリティ上の問題がないかレビューして」と依頼するのが有効です。
QCVE-2025-29927とは何ですか?
ANext.jsのx-middleware-subrequestヘッダーを悪用してミドルウェアの認可チェックをバイパスできる脆弱性です。この教訓から、認可チェックはミドルウェアだけでなくServer Component / API Route内でも二重に行うことが業界標準になりました。CLAUDE.mdに「二重チェック必須」と明記しておきましょう。
QClaude Codeに認証コードを書かせて大丈夫ですか?
ACLAUDE.mdにセキュリティルール(パスワードハッシュ化、CSRF対策、二重チェック等)を明記しておけば、Claude Codeは安全なパターンに従ったコードを生成します。ただし認証コードは必ず人間がレビューしてから本番デプロイしてください。Claude Codeセキュリティ完全ガイドもあわせてご覧ください。

まとめ

  • Better Auth: Auth.jsの後継。OSS・DB自前・MAU無制限。データ所有権を重視するプロジェクトに
  • Clerk: プリビルトUI + 公式MCP Server。最速実装。50K MAUまで無料
  • Supabase Auth: RLSでDBレベルの認可。PostgreSQL統合プロジェクトに
  • RBAC設計: ロール×権限マトリックスをClaude Codeに設計させ、ユーティリティ関数として実装
  • 二重チェック: ミドルウェア+Server Component / API Route の2箇所で認可チェック(CVE-2025-29927対策)
  • CLAUDE.md: セキュリティ基本方針・認可チェックルール・禁止事項を明記して生成品質を担保

Next.jsとの統合はClaude Code × Next.js完全ガイド、データベース設計はClaude Code × データベース開発ガイド、セキュリティ全般はClaude Codeセキュリティ完全ガイドもあわせてご覧ください。