Next.js × Clerk 認証:会員機能・組織管理(マルチテナント)とGoogleログインの簡単実装ガイド

公開日 2025.12.08
監修者 板鼻 祐治

目次

目次

Webサービスではもちろんですが、Webサービスだけでなく、メディアサイトなどでも会員向け記事などの会員サイトも多くあります。 Next.js で構築したWebサイトに会員機能(認証)を導入する際、最近注目されているのが Clerk です。

Googleアカウントでのログインや GitHubアカウントでのログインなどのソーシャルログイン、多要素認証、マルチテナント(B2B・組織管理)構成まで揃っており、UI コンポーネントも標準で提供されるため、初期構築の負担が大きく下がります。

この記事では、Next.jsにClerkを導入する方法と、ログイン後にユーザー名を表示するための実装ポイント、さらに実務的な運用で注意したい点まで解説します。

Clerk とは? Next.js開発の会員サイトで選ばれる理由

Clerk は会員機能(登録機能、ログイン機能、ユーザー管理機能)とUIをまとめて提供するサービスです。 Next.jsと組み合わせると特に扱いやすく、設定さえ済めばログインフォームやプロフィール編集などをそのまま設置できます。

Clerk が提供している主な機能

  • Google、Apple、GitHub などの OAuth

  • メールアドレスとパスワードによるログイン

  • 多要素認証(MFA)

  • 組織管理(Organizations)によるマルチテナント

  • 標準 UI(SignIn / SignUp / UserButton / Profile)

  • Webhook や API による拡張

他認証サービスとの比較

横にスクロールできます

サービス

特徴

向いているケース

Clerk

UI付き、Next.js向け、ソーシャルログイン強い

早く実装したい、UIまで任せたい

Supabase Auth

DB内蔵、拡張性が高い

DB主体で設計したい

Auth.js

OSS、自由度が高い

認証を細かく制御したい

Auth0

エンタープライズ向け

B2B・SSO が必須の大規模案件

Clerk は UI まで含めた「認証基盤」をまとめて構築できるため、実務において「時間をかけずに安全な認証を導入したい」ケースで非常に有効です。

また、企業ごとにデータを分ける「マルチテナント(組織管理)」機能も標準搭載されているため、将来的に B2B SaaS へと発展させる場合でもスムーズに対応できる点が大きな強みです。

Next.js への導入手順

ここからは、公式 Quickstart をもとに、Next.js で Clerk を導入するプロセスを丁寧に解説していきます。

参考:https://clerk.com/docs/nextjs/getting-started/quickstart

1. プロジェクトの準備

npx create-next-app@latest my-app
cd my-app
# 本体、日本語化用、Webhook検証用パッケージ
npm install @clerk/nextjs @clerk/localizations svix

Next.js 15であればこのまま問題なく動作すると思います。

2. Clerk の環境変数を設定

Clerk ダッシュボードで新しいアプリを作成し、APIキーを取得して .env.local に追加します。 また、独自ページを作成するため、リダイレクト先の URL 設定もここで行います。

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx

# アプリ内のログイン・登録ページを指定(必須設定)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

ポイント:自動検知のオーバーライド(上書き)とパスの指定 Clerk はデフォルト設定や自動検知でページを探そうとしますが、環境変数を設定することでその挙動を上書きし、任意のパスを正として指定できます

これにより、意図した URL(上記例では /sign-in)へ確実にリダイレクトさせることができます。もし将来的に URL を /login など別のパスに変更したくなった場合も、この環境変数を変更するだけで対応可能になります。

3. Middleware の作成

Next.js では middleware.ts が必須です。 Clerk v5 以降、デフォルトではすべてのページが「公開(ログイン不要)」として扱われるため、ダッシュボードやマイページなど、認証が必要なルートはここで明示的に保護する必要があります。

ルートディレクトリ(app/ と同階層)に作成してください。

// middleware.ts
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";

// 1. 認証が必要なルートを定義(例: /dashboard 以下と /forum 以下)
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']);

export default clerkMiddleware(async (auth, req) => {
  // 2. 定義したルートにアクセスがあった場合、ログインを強制する
  if (isProtectedRoute(req)) {
    await auth.protect();
  }
});

export const config = {
  matcher: [
    // Next.js の内部ファイルや静的ファイルを除外
    '/((?!_next|[^?]*\\\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // API ルートには常に適用
    '/(api|trpc)(.*)',
  ],
};

ポイント:

  • clerkMiddleware() を置くだけだと、認証状態(ログインしているかどうか)は判定されますが、ページへのアクセス制限はかかりません

  • createRouteMatcher でログイン必須にしたいパスを指定し、auth.protect() を呼ぶことで、未ログインユーザーをログインページへリダイレクトさせることができます。

4. ClerkProvider を layout.tsx に追加

アプリ全体のルートにあたる layout.tsx で Clerk を読み込みます。ここで日本語化設定(jaJP)も適用します。

// app/layout.tsx
import { ClerkProvider } from '@clerk/nextjs';
import { jaJP } from '@clerk/localizations';
import './globals.css';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <ClerkProvider localization={jaJP}>
      <html lang="ja">
        <body>{children}</body>
      </html>
    </ClerkProvider>
  );
}

これで Clerk の認証状態がアプリ全体で扱えるようになります。

Next.js にログイン機能を実装する(Googleログイン・ソーシャルログイン対応)

Clerk は ログイン(SignIn) / 登録(SignUp) を UI として提供しているため、Next.js 側ではページを作るだけで機能します。

1. ログイン(SignIn)ページの作成

// app/sign-in/[[...sign-in]]/page.tsx
import { SignIn } from '@clerk/nextjs';

export default function Page() {
  return (
    <div className="flex justify-center py-24">
      <SignIn />
    </div>
  );
}

2. 登録(SignUp)ページの作成

// app/sign-up/[[...sign-up]]/page.tsx
import { SignUp } from '@clerk/nextjs';

export default function Page() {
  return (
    <div className="flex justify-center py-24">
      <SignUp />
    </div>
  );
}

これだけでメール認証・パスワード設定・Googleログインなどが統合された画面が表示されます。

3. Google OAuth の有効化

Clerk ダッシュボード → Configure → SSO Connections から Google を ON にします。 開発環境(Development)では、Clerk が提供する共有設定が自動的に適用されるため、これだけで Google ログインが機能します。

注意:本番環境(Production)へのデプロイ時 本番公開する際は、Google Cloud Console で正式に OAuth クライアントを作成し、ID と Secret を Clerk に設定(Use custom credentials を ON に)する必要があります。

認証後ヘッダーにユーザー情報を表示する(CSR + useUser)

Next.js では、ヘッダーなど UI 部分を CSR で書くケースが多いため、useUser() を利用すると扱いやすくなります。 以下は「登録/ログインボタン」と「ユーザー名表示」と「UserButton」をひとまとめにした実践的なパターンです。

Google ログイン直後など username が無いケースを考慮し、メールアドレス等へのフォールバックを含めています。

SignInOut コンポーネント(実装例)

'use client';

import {
  SignedIn,
  SignedOut,
  SignInButton,
  SignUpButton,
  UserButton,
  useUser,
} from '@clerk/nextjs';

export default function SignInOut() {
  const { user } = useUser();

  // 表示優先順位: username -> fullName -> email -> ゲスト
  const displayName =
    user?.username ??
    user?.fullName ??
    user?.primaryEmailAddress?.emailAddress ??
    'ゲスト';

  return (
    <div className="flex items-center gap-2">
      <SignedOut>
        <SignUpButton mode="modal">
          <button className="h-10 cursor-pointer rounded-full bg-blue-500 px-4 text-sm font-medium text-white">
            登録
          </button>
        </SignUpButton>
        <SignInButton mode="modal">
          <button className="h-10 cursor-pointer rounded-full border border-blue-500 px-4 text-xs font-medium text-blue-700">
            ログイン
          </button>
        </SignInButton>
      </SignedOut>

      <SignedIn>
        <span className="text-xs">
          {displayName} さん
        </span>
        <UserButton showName={false} />
      </SignedIn>
    </div>
  );
}

ポイント:

  • 冒頭に 'use client' を入れ、コンポーネントを CSR 化している

  • ユーザー名は usernamefullNameemail の順で表示(Googleログイン対策)

  • UserButton を使うと自動的にアイコン+メニューを表示

  • SignedIn / SignedOut により表示振り分けが自然に行える

Clerk を「そのまま使うだけ」は危険?Webhook / Svix の同期が必要な理由

Clerk は認証基盤として優れていますが、「ユーザー関連の全データを Clerk 側に置くだけ」の構成は実務ではあまり推奨されません。 海外の開発者コミュニティでも、以下のような指摘があります。

  • Clerk の ID とアプリ側のデータ ID を紐づけておきたい

  • メールアドレスの変更や削除に応じてアプリの DB も更新する必要がある

  • 権限・プラン・購入履歴などアプリ固有の情報は Clerk では管理できない

  • マルチテナント構成では整合性が重要

このため、Webhook(Svix)を使って「ユーザー作成・更新・削除」をバックエンドで受信し、自前 DB に反映しましょう。

Webhook 実装例(Next.js App Router / Route Handler)

Next.js 15 以降の非同期ヘッダー処理に対応したコードです。

// app/api/webhooks/clerk/route.ts
import { Webhook } from "svix";
import { headers } from "next/headers";
import { WebhookEvent } from "@clerk/nextjs/server";

export async function POST(req: Request) {
  const webhookSecret = process.env.CLERK_WEBHOOK_SECRET!;

  // Next.js 15対応: headers() は await が必要
  const headerPayload = await headers();
  const svix_id = headerPayload.get("svix-id");
  const svix_timestamp = headerPayload.get("svix-timestamp");
  const svix_signature = headerPayload.get("svix-signature");

  if (!svix_id || !svix_timestamp || !svix_signature) {
    return new Response('Error occured -- no svix headers', { status: 400 });
  }

  const payload = await req.json();
  const body = JSON.stringify(payload);

  const wh = new Webhook(webhookSecret);
  let evt: WebhookEvent;

  try {
    evt = wh.verify(body, {
      "svix-id": svix_id,
      "svix-timestamp": svix_timestamp,
      "svix-signature": svix_signature,
    }) as WebhookEvent;
  } catch (err) {
    console.error('Error verifying webhook:', err);
    return new Response('Error occured', { status: 400 });
  }

  const eventType = evt.type;

  // ユーザー作成・更新時の処理
  if (eventType === 'user.created' || eventType === 'user.updated') {
    const { id, email_addresses } = evt.data;
    const email = email_addresses[0]?.email_address;

    // ここでユーザー作成や削除を DB に反映 (例: Prisma.upsert)
    console.log(`User synced: ${id}, ${email}`);
  }

  // ユーザー削除時の処理
  if (eventType === 'user.deleted') {
      // DB からユーザーを削除または無効化
  }

  return new Response("OK", { status: 200 });
}

同期対象として最低限扱うデータは次の通りです。

  • userId(Clerk のユーザーID)

  • email

  • username / fullName

  • tenantId(Organizations を使用する場合)

Webhook を適切に運用することで、認証とアプリデータの整合性を保つことができ、本番運用に耐えられる認証基盤になります。

マルチテナント(B2B・組織管理) × Clerk × Next.js の構成例

マルチテナントとは、企業が組織として利用する場合の考え方になります。

たとえば、Google WorkspaceやSlackのようなイメージです。

Clerk の Organizations 機能は、SaaS などのマルチテナント構成を簡単に実装できる仕組みです。

Organizations を使う構成の特徴

  • 組織管理・ロール管理が Clerk 側で完結

  • Next.js 側では useOrganization() などで情報取得

  • 権限によって UI を出し分けるだけで済む

独自バックエンドで管理する構成

  • テナントデータを自前 DB で保持

  • Clerk はあくまで認証専用

  • Webhook で userId と tenantId を同期

中規模までは Organizations で十分ですが、「複雑な権限管理」「外部システム連携」が必要になると自前構築の割合が増えます。

よくある質問(FAQ)

Q. Next.js で認証システムを作る場合、Clerk を使うメリットは何ですか?

Clerk は Next.js との統合が非常にスムーズで、Google OAuth やソーシャルログイン、多要素認証といった機能を短期間で実装できます。

自前でログイン画面やパスワードリセットを作り込む必要が減るため、Webアプリの MVP 開発や SaaS の初期構築で採用されるケースがあります。

Q. Google ログイン(Google OAuth)だけで認証を運用するのは不十分ですか?

Google OAuth だけでも認証は成立しますが、一般的には「ユーザー管理画面」「パスワードレス認証」「マルチテナント管理」などが必要になる場面があります。

Clerk はこれらをまとめて提供するため、Next.js でサービスを開発する際は全体の開発工数を抑えやすくなります。

Q. セッション管理やセキュリティ対策は Clerk に任せても大丈夫ですか?

多くのケースでは、セッション管理・多要素認証(MFA)・デバイストラッキングなどはサービス側で実装するより、専用サービスに任せる方が一般的です。

Clerk もこうした領域を担当する設計になっており、Next.js での構築と相性が良いと言われています。

Q. マルチテナント構成(multi-tenant)は Clerk Organizations だけで実現できますか?

要件によりますが、小規模〜中規模の SaaS であれば Clerk Organizations で完結するケースもあります。

より複雑な権限管理や外部サービス連携が必要な場合は、自前のバックエンドと併用しながらアーキテクチャを設計することが多いです。

Q. Auth0 や Firebase Authentication と比べて、Clerk を選ぶ理由は何ですか?

どれも優れた認証サービスですが、Next.js アプリの開発では Clerk が UI コンポーネントや Google / GitHub などのソーシャルログインの統合が簡単な点が評価されます。

特に App Router との相性が良いため、フロントエンド中心でサービス開発を進める企業が選ぶケースがあります。

Q. Clerk の MAU 課金が心配ですが、コスト管理はしやすいですか?

MAU 課金のサービスはユーザー数やサービスの成長に応じて費用が変動します。

Clerk ではダッシュボードでセッション数やアクティブユーザーを確認できるため、Next.js のアプリ運用と合わせて定期的にモニタリングすることが大事です。

Q. Next.js App Router で Clerk を使う場合、技術的に気をつける点はありますか?

App Router では「RSC と CSR の使い分け」が重要と言われています。

Clerk では、RSC で currentUser(), CSR で useUser() を使うという設計が基本で、これはどの認証サービスでも要求される一般的な Next.js の仕様です。

Q. Clerk を導入した後、他の認証サービスに切り替えるのは難しいですか?

ケースによりますが、一般的にはユーザーテーブルを自前で持っていれば移行は可能です。

認証サービスの選択はアプリの要件・運用体制・セキュリティ基準によって変わるため、どれが最適というより「運用方針に合うものを選ぶ」という判断が多いです。

Q. 結局、どんなプロジェクトに Clerk が向いていますか?

Next.js ベースで、ソーシャルログインや Google OAuth、ユーザープロフィール、マルチテナントなどを短期間で実装したい Webアプリや SaaS に適しています。

ログインの UI・セキュリティ・セッション管理をサービス側に持たせたい場合に選ばれやすい傾向があります。

まとめ

Clerk は Next.js と非常に相性が良く、Google を含むソーシャルログイン、多要素認証、プロフィール編集、マルチテナントまでまとめて提供してくれます。 導入も数ステップで完了し、UI まで含めて認証まわりの実装を最低限に抑えることができます。

一方、実務では Clerk 側だけにユーザーデータを保持するのではなく、Webhook を使ったバックエンド同期が重要になります。 この点を押さえることで、長期的に安全かつ柔軟な認証基盤を構築することができます。 Next.js × Clerk は、スピードと保守性を両立しながら認証を実装したいプロジェクトにとって非常に有力な選択肢です。

要件定義からシステム設計、開発なら株式会社デパートにおまかせ

株式会社デパートでは、要件定義からシステム設計、開発を一貫して対応可能です。

システム設計・開発サービスをご紹介

Contact

制作のご依頼やサービスに関するお問い合わせ、
まだ案件化していないご相談など、
お気軽にお問い合わせください。

お問い合わせはこちら

関連ブログ