Clerk 認証パターン は何をしますか?
クイックガイド: Clerkは、プリビルドUIコンポーネント、サーバーサイドヘルパー、組織ベースのマルチテナンシーを備えた管理型認証を提供します。ルート保護には
clerkMiddleware()、条件付きレンダリングには<Show>、クライアント状態にはフック、サーバーサイド認証にはauth()/currentUser()を使用します。Clerk Core 3(2026年)では、<SignedIn>/<SignedOut>が<Show>に置き換わり、Next.js 16以降ではミドルウェアファイル名がproxy.tsに変更され、パッケージが統合されます。
<critical_requirements>
重要: このスキルを使用する前に
すべてのコードは CLAUDE.md のプロジェクト規約に従うこと(kebab-case、名前付きエクスポート、インポート順序、
import type、名前付き定数)
(サーバーサイドのインポートは常に
@clerk/nextjs/serverを使用すること --@clerk/nextjsからサーバーヘルパーをインポートしないでください)
(Webhookは Clerk の
verifyWebhookヘルパーを使用して必ず検証すること -- 未検証のWebhookペイロードを信頼しないでください)
(
<SignedIn>/<SignedOut>/<Protect>は非推奨であり、代わりに<Show>コンポーネントを使用すること -- これらはCore 3で削除されました)
(
currentUser()オブジェクト全体をクライアントに渡さないこと -- サーバーサイドに留めるべきprivateMetadataが含まれています)
(ルートはミドルウェアとデータアクセス層の両方で保護すること -- ミドルウェアだけでは不十分です)
</critical_requirements>
自動検出: Clerk、ClerkProvider、clerkMiddleware、@clerk/nextjs、useUser、useAuth、useClerk、useSession、useOrganization、SignIn、SignUp、UserButton、UserProfile、OrganizationSwitcher、auth()、currentUser()、CLERK_SECRET_KEY、NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY、Show when="signed-in"
使用すべき場合:
- アプリケーションに認証とユーザー管理を追加する場合
- 組織ベースのアクセス制御を備えたマルチテナントB2Bアプリを構築する場合
- カスタマイズ可能なテーマを持つプリビルドのサインイン/サインアップUIコンポーネントを使用する場合
- ミドルウェアとサーバーサイドの認可チェックでルートを保護する場合
- Webhookを介してClerkユーザーデータをデータベースに同期する場合
カバーする主要パターン:
- ClerkProviderのセットアップ、環境変数、ミドルウェア設定
- プリビルドUIコンポーネント(
<SignIn>、<SignUp>、<UserButton>、<Show>) - クライアントサイドフック(
useUser、useAuth、useSession、useOrganization) - サーバーコンポーネント、ルートハンドラー、サーバーアクションでのサーバーサイド認証(
auth()、currentUser()) clerkMiddleware()とcreateRouteMatcher()を使用したミドルウェアルート保護- ロールと権限を使用した組織ベースのマルチテナンシー
- Svix署名検証を使用したWebhook処理
使用すべきでない場合:
- セルフホスト型認証が必要な場合(認証データストレージを完全に制御する必要がある)
- サードパーティの認証サービスを使用できない場合(コンプライアンス/規制上の制約)
- アプリが単純なAPIキー認証のみを必要とする場合
- 予算の制約によりマネージドサービスの使用が不可能な場合
詳細リソース:
- reference.md - 決定フレームワーク、フッククイックリファレンス、Core 3移行チートシート
- examples/core.md - ClerkProvider、環境変数、ミドルウェア設定
- examples/components.md - プリビルドコンポーネント、カスタマイズ、appearanceプロパティ
- examples/hooks.md - useUser、useAuth、useSession、ローディング状態、条件付きレンダリング
- examples/server.md - サーバーコンポーネント、APIルート、サーバーアクション、Webhook処理
- examples/organizations.md - 組織管理、ロール、権限、RBAC
哲学
Clerkは管理型認証プラットフォームであり、サインアップ、サインイン、セッション管理、ユーザープロファイル、組織、多要素認証(MFA)など、認証ライフサイクル全体を処理します。認証をゼロから構築する代わりに、ClerkのSDKとプリビルドコンポーネントを統合します。
中核となる原則:
- 多層防御 -- ミドルウェア層でルートを保護し、さらにすべてのデータアクセスポイントで認証を検証します。ミドルウェアだけでは不十分です(CVE-2025-29927はミドルウェアバイパスの脆弱性を示しました)。
- サーバーファーストの認証 -- サーバーコンポーネントとルートハンドラーでは
auth()とcurrentUser()を使用します。リアクティブなクライアントサイド状態が必要な場合にのみ、クライアントフック(useUser、useAuth)を使用します。 - カスタムよりプリビルド -- Clerkの
<SignIn>、<SignUp>、<UserButton>コンポーネントを使用します。プリビルドコンポーネントが本当に要件を満たせない場合にのみ、カスタムフローを構築します。 - マルチテナンシーのための組織 -- B2Bアプリには、ロールと権限を持つClerk組織を使用します。Clerkのユーザーモデルの上にカスタムテナントシステムを構築しないでください。
- Webhook駆動の同期 -- ポーリングではなく、Webhookを介してClerkデータをデータベースに同期します。常に
verifyWebhookでWebhook署名を検証します。
Clerkを使用すべき場合:
- 最小限のカスタムコードで迅速に認証が必要な場合
- サインイン/サインアップ/ユーザー管理用のプリビルドUIコンポーネントが必要な場合
- RBACを使用した組織ベースのマルチテナンシーが必要な場合
- 管理されたMFA、SSO(SAML/OIDC)、ソーシャルログインが必要な場合
Clerkを使用すべきでない場合:
- 認証データストレージを完全に制御する必要がある場合(セルフホスト要件)
- サードパーティの認証サービスを使用できない場合(コンプライアンス/規制)
- アプリが単純なAPIキー認証のみを必要とする場合
- 予算の制約によりマネージドサービスの使用が不可能な場合
コアパターン
パターン1: ClerkProviderとミドルウェアのセットアップ
すべてのClerkアプリは、アプリをラップする <ClerkProvider> とルートを保護する clerkMiddleware() を必要とします。完全なセットアップ例については examples/core.md を参照してください。
主要ルール:
ClerkProviderは<body>内に配置し、<html>をラップしないでください -- Core 3ではこれが必要ですNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY環境変数を使用し、キーをハードコードしないでください- ミドルウェアファイルは Next.js 16以降では
proxy.ts、Next.js 15以下ではmiddleware.tsです - Webhookエンドポイントはパブリックルートリストに含める必要があります(
verifyWebhookによって個別に検証されます) - Webhook署名用の環境変数は
CLERK_WEBHOOK_SIGNING_SECRETです(CLERK_WEBHOOK_SECRETではありません)
// proxy.ts (Next.js 16+) または middleware.ts (Next.js <=15)
const isPublicRoute = createRouteMatcher([
"/",
"/sign-in(.*)",
"/sign-up(.*)",
"/api/webhooks(.*)",
]);
export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) {
await auth.protect();
}
});
なぜ良いか: パブリックルートが明示的にホワイトリストに登録され、それ以外はすべて認証が必要、Webhookエンドポイントはパブリック(個別に検証される)
// BAD: コールバックなしのclerkMiddleware()
export default clerkMiddleware(); // すべてのルートがデフォルトでパブリック!
なぜ悪いか: コールバックなしの clerkMiddleware() は認証データをアタッチしますが、ルートを保護しません
パターン2: プリビルドUIコンポーネントと <Show>
条件付きレンダリングには <Show> を使用します(Core 3で <SignedIn>/<SignedOut>/<Protect> を置き換え)。完全な例については examples/components.md を参照してください。
<Show when="signed-out"><SignInButton /></Show>
<Show when="signed-in"><UserButton /></Show>
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>
<Show when={(has) => has({ permission: "org:invoices:manage" })}><InvoiceManager /></Show>
なぜ良いか: <Show> はCore 3のAPIであり、文字列/オブジェクト/コールバック条件をサポートし、許可されていない場合の fallback プロパティも備えています
// BAD: 非推奨 -- Core 3で削除済み
<SignedIn>...</SignedIn>
<SignedOut>...</SignedOut>
<Protect role="admin">...</Protect>
なぜ悪いか: <SignedIn>、<SignedOut>、<Protect> はCore 3で削除されました。代わりに when プロパティを持つ <Show> を使用してください
サインイン/サインアップページでは、多段階フロー(MFA、OAuthコールバック)のためにキャッチオールルートセグメント [[...sign-in]] が必要です。
パターン3: クライアントサイドフック
リアクティブな認証状態のために、Client Componentsでフックを使用します。データにアクセスする前に、常に isLoaded を確認してください。完全な例については examples/hooks.md を参照してください。
"use client";
const { isLoaded, isSignedIn, user } = useUser();
if (!isLoaded) return <div>Loading...</div>;
if (!isSignedIn) return <div>Please sign in</div>;
// これで user.firstName、user.emailAddresses などに安全にアクセスできます
なぜ良いか: 初期化中に undefined にアクセスする際のハイドレーションエラーを防ぎ、サインアウト時に null にアクセスする際のTypeErrorを防ぎます
// BAD: ガードなしでuserにアクセス
const { user } = useUser();
return <p>{user.firstName}</p>; // isLoaded=false または isSignedIn=false のときにランタイムエラー
なぜ悪いか: user はロード完了までは undefined、サインアウト時は null です
主要フック:
useUser()-- ユーザープロファイルデータ(名前、メール、アバター)useAuth()-- セッショントークン (getToken())、userId、orgId、認可用のhas()useOrganization()-- アクティブな組織データ、メンバーシップ、ページングされたメンバーリストuseReverification()-- 機密アクションの前に再認証(Core 3)
Core 3では、getToken() はオフライン時に null を返す代わりに ClerkOfflineError をスローします -- 常にtry/catchでラップしてください。
パターン4: サーバーサイド認証
@clerk/nextjs/server から auth() と currentUser() を使用します。完全な例については examples/server.md を参照してください。
auth() -- 軽量、API呼び出しなし、セッションクレームを読み取り:
import { auth } from "@clerk/nextjs/server";
const { userId, orgId, isAuthenticated, redirectToSignIn } = await auth();
if (!isAuthenticated) return redirectToSignIn();
currentUser() -- 完全なユーザーオブジェクト、バックエンドAPIを呼び出す:
import { currentUser } from "@clerk/nextjs/server";
const user = await currentUser();
// 重要: クライアントコンポーネントに渡す前に安全なフィールドのみを選択
const safeData = { firstName: user.firstName, imageUrl: user.imageUrl };
なぜ重要か: currentUser() は privateMetadata を返しますが、これは決してクライアントに到達してはなりません。フィールドを明示的に選択してください。
多層防御: 認証は、ミドルウェアだけでなく、すべてのサーバーアクションとルートハンドラーでチェックする必要があります:
"use server";
const { userId } = await auth();
if (!userId) throw new Error("Unauthorized");
// userId はすべてのクエリ/ミューテーションを現在のユーザーにスコープします
パターン5: ロールと権限を使用した認可
きめ細かなアクセス制御には auth.protect() または has() を使用します。RBACパターンについては examples/organizations.md を参照してください。
// ミドルウェア: ロールベースのルート保護
await auth.protect((has) => has({ role: "org:admin" }));
// サーバーコンポーネント: 権限チェック
const { has } = await auth();
if (!has({ permission: "org:invoices:delete" })) redirect("/dashboard");
// クライアント: ロールによる条件付きレンダリング
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>
権限の形式: org:<feature>:<action>(例: org:invoices:create、org:reports:read)
デフォルトロール: org:admin(すべての権限)、org:member(読み取り専用)。カスタムロールはClerk Dashboardで設定します。
パターン6: Webhook処理
Clerk Webhook(Svix経由)を使用して、ユーザーデータをデータベースに同期します。完全なハンドラーについては examples/server.md を参照してください。
import { verifyWebhook } from "@clerk/nextjs/webhooks";
export async function POST(req: Request) {
const evt = await verifyWebhook(req); // CLERK_WEBHOOK_SIGNING_SECRET 環境変数を読み取ります
// evt.type: "user.created" | "user.updated" | "user.deleted" | "organization.*" | ...
// evt.data: UserJSON | OrganizationJSON | など
}
なぜ良いか: verifyWebhook はSvix署名を検証し、常に200を返して再試行を防ぎ、Webhookルートはミドルウェアでパブリックです(認証ではなく署名によって検証されます)
// BAD: 署名検証なし
const body = await req.json(); // 誰でも偽のデータをPOSTできる!
await db.insert(users).values(body.data); // セキュリティ脆弱性
なぜ悪いか: 署名検証がないため、誰でも偽のWebhookイベントをエンドポイントに送信できます
Core 3では @clerk/shared/types から型をインポートします: UserJSON、OrganizationJSON、OrganizationMembershipJSON
<decision_framework>
決定フレームワーク
クライアント vs サーバー認証
認証データはどこで必要ですか?
|-- サーバーコンポーネント、ルートハンドラー、サーバーアクション
| |-- userId/sessionIdだけが必要? --> auth()
| |-- 完全なユーザーオブジェクトが必要? --> currentUser()
| |-- ルートを保護する必要がある? --> auth.protect()
| +-- 組織コンテキストが必要? --> auth() は orgId、orgRole を返します
|
+-- クライアントコンポーネント(インタラクティブUI)
|-- ユーザープロファイルデータが必要? --> useUser()
|-- セッション/トークンデータが必要? --> useAuth()
|-- 組織データが必要? --> useOrganization()
+-- 低レベルClerk APIが必要? --> useClerk()
ルート保護戦略
どのようなルートですか?
|-- パブリック(ランディング、サインイン、サインアップ、Webhook)
| +-- isPublicRouteマッチャーに追加し、auth.protect() をスキップ
|
|-- 認証済み(ダッシュボード、プロフィール、設定)
| +-- ミドルウェアでの auth.protect() + データ層での auth() チェック
|
+-- 認可済み(管理、組織固有、権限ゲート)
|-- ロールベース? --> auth.protect({ role: "org:admin" })
+-- 権限ベース? --> auth.protect((has) => has({ permission: "org:feature:action" }))
コンポーネントの選択
どの認証UIが必要ですか?
|-- 完全なサインインページ --> キャッチオールルート上の <SignIn />
|-- 完全なサインアップページ --> キャッチオールルート上の <SignUp />
|-- サインインボタン(モーダル) --> <SignInButton />
|-- ユーザーアバター + メニュー --> <UserButton />
|-- 完全なプロフィールエディター --> <UserProfile />
|-- 組織切り替え --> <OrganizationSwitcher />
+-- 条件付きコンテンツ --> <Show when="signed-in"> または <Show when={{ role: "..." }}>
</decision_framework>
<red_flags>
レッドフラグ
高優先度の問題:
@clerk/nextjsではなく@clerk/nextjs/serverからサーバーヘルパーをインポートする(サーバーコンポーネントで壊れます)- 非推奨の
<SignedIn>/<SignedOut>/<Protect>コンポーネントを使用する(Core 3で削除済み) currentUser()オブジェクト全体をクライアントコンポーネントに渡す(privateMetadataが漏洩します)verifyWebhook署名検証なしでWebhookペイロードを信頼する- ルート保護をミドルウェアのみに依存する(ミドルウェアはバイパスされる可能性があります)
@clerk/typesではなく@clerk/shared/typesから型をインポートする(Core 3の移行)
中程度の問題:
NEXT_PUBLIC_環境変数を使用せずに公開可能鍵をハードコードする- フックデータにアクセスする前に
isLoadedチェックを省略する useUser()とuseAuth()を混同する(useUser()はプロファイル用、useAuth()はトークンとID用)- 多段階フロー(MFA、検証)のためにサインイン/サインアップルートにキャッチオールセグメント
[[...sign-in]]を使用しない getToken()呼び出しをtry/catchでラップしない(Core 3ではオフライン時にClerkOfflineErrorをスローします)