Communitygithub.com

Clerk 認証パターン

ClerkProvider、ミドルウェア、プリビルドコンポーネント、フック、サーバーサイド認証、組織管理、Webhookを利用したClerk管理型認証。

Clerk 認証パターン とは?

このスキルは、Clerkを利用した認証システムを効率的に構築・統合するための包括的なパターン集です。ClerkProviderのセットアップ、clerkMiddleware()によるルート保護、プリビルドUIコンポーネント(<SignIn>、<Show>など)、クライアントサイドフック(useUser、useAuth)、サーバーサイド認証(auth()、currentUser())、組織ベースのマルチテナント(RBAC)、Webhookによるデータ同期など、主要な認証パターンをカバーします。特に、Next.js 16以降で推奨されるCore 3 API(<Show>による条件付きレンダリング、proxy.tsへのミドルウェアファイル名変更、パッケージ統合)に完全対応しており、非推奨APIの使用を防止します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agents-inc/skills/tree/HEAD/src/skills/api-auth-clerk

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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とプリビルドコンポーネントを統合します。

中核となる原則:

  1. 多層防御 -- ミドルウェア層でルートを保護し、さらにすべてのデータアクセスポイントで認証を検証します。ミドルウェアだけでは不十分です(CVE-2025-29927はミドルウェアバイパスの脆弱性を示しました)。
  2. サーバーファーストの認証 -- サーバーコンポーネントとルートハンドラーでは auth() と currentUser() を使用します。リアクティブなクライアントサイド状態が必要な場合にのみ、クライアントフック(useUser、useAuth)を使用します。
  3. カスタムよりプリビルド -- Clerkの <SignIn>、<SignUp>、<UserButton> コンポーネントを使用します。プリビルドコンポーネントが本当に要件を満たせない場合にのみ、カスタムフローを構築します。
  4. マルチテナンシーのための組織 -- B2Bアプリには、ロールと権限を持つClerk組織を使用します。Clerkのユーザーモデルの上にカスタムテナントシステムを構築しないでください。
  5. 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 をスローします)

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

関連スキル