セキュリティ

Clerk認証とは?Next.jsへの導入手順とCore 3の変更点・MRU料金・Auth0との選び分け【2026年10月】

会員管理システムにおける主な機能一覧

Clerkは、サインイン画面・ユーザー管理・セッション管理をまとめて外部化できる、React・Next.jsに寄せた認証SaaSです。この記事では、Next.js 16へClerk認証を組み込む手順をコード付きで示し、2026年3月のCore 3で変わった書き方、60秒で失効するセッショントークンの仕組み、日本語化できる範囲と英語のまま残る画面、MRU課金の料金を整理します。最後に、Auth0やAuth.jsとの選び分けを条件付きで言い切ります。

まとめ:Clerk認証をReact案件で採用する条件と見送る場面

Next.jsやReactでB2Cの会員機能を短期間で出す案件なら、Clerkは有力な選択肢です。サインイン画面とプロフィール画面がコンポーネントで提供され、アプリ側の作業は鍵の設定・Providerの配置・サーバー側の認可判定にほぼ絞られます。無料のHobbyでも1アプリあたり50,000MRUまで使えます。

見送るのは、Next.js以外のバックエンドが主役の構成、SAML接続を多数抱えるB2B、ログイン周りの全画面を日本語で揃える必要がある案件です。2026年10月時点の最新SDKは@clerk/nextjs 7.9系で、Core 3以前の記事にあるauthMiddlewareやcreateRouteMatcher前提の書き方は、そのまま写さないでください。

Clerk認証の仕組み:2種類のトークンとSDKが受け持つ処理の範囲

Clerkを入れると、ユーザーのパスワードやソーシャルログインの連携情報はClerk側に保存され、アプリは「誰がログインしているか」を署名付きトークンで受け取るだけになります。

Clerkが肩代わりする範囲:画面部品・ユーザー台帳・セッション発行

Clerkが提供するのは、SignInやUserButtonなどのReactコンポーネント、ユーザーと組織(Organizations)の台帳、セッショントークンの発行と更新です。メール+パスワード、メールコード、Google・GitHubなどのソーシャルログインはダッシュボードの切り替えで有効にできます。

アプリ側に残る仕事は、どの画面・どのAPIを誰に許すかという認可の判定です。SDKは公式リポジトリclerk/javascriptにまとまっており、Next.js用・React用・Express用・サーバー検証用(@clerk/backend)が同じ版系列で公開されています。

__clientと__sessionの2つのCookie、50秒ごとに走る自動更新

公式のHow Clerk worksによると、Clerkは長命のクライアントトークンと短命のセッショントークンを組み合わせています。クライアントトークンはClerkのFrontend APIのドメインに__clientというHttpOnly Cookieで置かれ、セッションの正本になります。

アプリのドメインに置かれる__sessionは有効期限60秒のJWTです。フロントエンドSDKが50秒間隔で更新を呼ぶため、ユーザーを強制ログアウトしても既発行トークンは最長60秒で失効します。サーバー側はこのJWTの署名を検証するだけで済み、リクエストごとにClerkへ問い合わせる必要はありません。

項目 クライアントトークン セッショントークン
Cookie名 __client __session
置き場所 Frontend APIのドメイン アプリのドメイン
有効期限 ブラウザ依存 60秒
HttpOnly あり なし

本番ではclerk.example.comのようにFrontend APIを自社サブドメインへCNAMEで向けるため、DNSの設定作業が発生します。

Next.js 16のClerk導入:clerk initとproxy.ts作成

ここからは公式のNext.js Quickstartに沿って、App Routerのアプリへ組み込む作業を順に示します。

clerk initで鍵とproxy.tsを生成する手順と環境変数の置き場所

Clerk CLIのinitを実行すると、パッケージの追加、.env.localへの鍵の書き込み、proxy.tsの生成までが一度に済みます。Next.js 16以降はproxy.ts、15以前はmiddleware.tsが作られ、中身はどちらもclerkMiddleware()の呼び出しです。

npx -y clerk@latest init --framework next --pm npm
npx -y clerk@latest doctor

# .env.local(initが書き込む)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxxxxx
CLERK_SECRET_KEY=sk_test_xxxxxxxx

CLERK_SECRET_KEYはサーバー専用です。NEXT_PUBLIC_を付けた変数へ移すとブラウザに配布されるため、Vercelなどの環境変数でも公開側に置かないでください。

layout.tsxにClerkProviderとShowを置いてサインイン画面を出す

次にルートレイアウトの<body>内をClerkProviderで包み、ログイン状態で表示を切り替えます。Core 3からはShowコンポーネントのwhen属性で切り替える書き方が標準です。

// app/layout.tsx
import { ClerkProvider, SignInButton, SignUpButton, Show, UserButton } from '@clerk/nextjs'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>
        <ClerkProvider>
          <header>
            <Show when="signed-out"><SignInButton /><SignUpButton /></Show>
            <Show when="signed-in"><UserButton /></Show>
          </header>
          {children}
        </ClerkProvider>
      </body>
    </html>
  )
}

この時点でnpm run devを起動すると、Clerkがホストするサインイン画面へ遷移し、登録とログインまで動きます。

Server ComponentとRoute Handlerの未認証アクセス拒否

画面やAPIの保護は、データを読む場所でauth()を呼んで判定します。auth()のリファレンスにあるとおり非同期関数なので、必ずawaitを付けます。

// app/dashboard/page.tsx
import { auth } from '@clerk/nextjs/server'

export default async function Dashboard() {
  const { isAuthenticated, redirectToSignIn, userId } = await auth()
  if (!isAuthenticated) return redirectToSignIn()
  return <p>ログイン中のユーザー: {userId}</p>
}

// app/api/orders/route.ts
export async function GET() {
  const { isAuthenticated, userId } = await auth()
  if (!isAuthenticated) return new Response('Unauthorized', { status: 401 })
  // userIdで絞り込んだ注文だけを返す
}

APIでは「ログインしているか」に加えて「そのuserIdのデータか」まで照合します。他人の注文IDを指定されても返さない条件を、SQLの絞り込みに入れておくのが基本です。

Core 3で変わったClerkの書き方:パッケージ改名と認可位置の見直し

npm registryの公開日を見ると、@clerk/nextjs 7.0.0と@clerk/react 6.0.0は2026年3月3日に出ています。これがCore 3で、それ以前の解説記事のコードは一部が動かないか非推奨です。

Core 3移行時のパッケージ改名と認証表示コンポーネントの対応表

Core 3のアップグレードガイドで示された主な変更を表にまとめます。移行はnpx @clerk/upgradeでコードを自動変換してから、残りを手で直す順番が推奨されています。

Core 2までの書き方 Core 3以降
@clerk/clerk-react @clerk/react(旧名は非推奨)
SignedIn・SignedOut Show when=”signed-in”など
Protect Showによる表示制御
afterSignInUrl fallbackRedirectUrl
redirectUrl fallbackRedirectUrl
Next.js 13・14対応 Next.js・Node.jsの対応下限を変更

Core 3の対応下限はNext.js 15.2.3以上・Node.js 20.9.0以上です。Next.js 14のまま運用しているアプリは、Clerkの更新より先にNext.js本体の更新計画が要ります。

createRouteMatcherでの一括保護をやめ、データ取得側で判定する理由

clerkMiddleware()のリファレンスでは、パス単位で保護するcreateRouteMatcher()が非推奨と明記され、データを読み書きするコードの近くで認可する方式へ移るよう案内されています。

背景には、ミドルウェアだけに認可を任せる設計の弱さがあります。2025年にはNext.jsミドルウェアの認可を迂回できるCVE-2025-29927が公表されました。proxy.tsはセッションの受け渡しに使い、権限の判定はページ・Route Handler・Server Actionの中で行う二段構えにしておくと、同種の欠陥が出ても被害が広がりません。

Next.js以外のバックエンドでClerkのJWTを検証する手順と同期処理

フロントはNext.js、APIはExpressや別言語という構成では、APIサーバー側でセッショントークンを検証する処理を自分で組みます。

authenticateRequestによる公開鍵と許可オリジンの検証例

Manual JWT verificationでは、@clerk/backendのauthenticateRequest()を使う方法が推奨されています。jwtKeyに公開鍵を渡すと、Clerkへ通信せずに署名・有効期限を検証できます。

import { createClerkClient } from '@clerk/backend'

const clerk = createClerkClient({
  secretKey: process.env.CLERK_SECRET_KEY,
  publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
})

export async function handler(req: Request) {
  const { isAuthenticated } = await clerk.authenticateRequest(req, {
    authorizedParties: ['https://app.example.com'],
    jwtKey: process.env.CLERK_JWT_KEY,
  })
  if (!isAuthenticated) return new Response('Unauthorized', { status: 401 })
}

authorizedPartiesはトークンのazpクレームと照合する許可オリジンの一覧です。省略するとCSRFの余地が残ると公式に書かれているため、本番では必ず指定します。署名方式はRS256で、検証の考え方はJWTの構造と署名検証の仕組みと同じです。

Webhookでユーザーを自社DBへ同期するときの遅延と取りこぼし対策

注文テーブルなどからユーザーを参照するため、Clerkのユーザーを自社DBへ写すことがあります。Webhook同期のガイドではuser.created・user.updated・user.deletedを受け、CLERK_WEBHOOK_SIGNING_SECRETで署名を検証します。

// app/api/webhooks/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks'
import type { NextRequest } from 'next/server'

export async function POST(req: NextRequest) {
  try {
    const evt = await verifyWebhook(req)
    if (evt.type === 'user.created') {
      // evt.data.id をキーに自社DBへupsertする
    }
    return new Response('ok')
  } catch {
    return new Response('Error verifying webhook', { status: 400 })
  }
}

同じガイドに、配信は保証されず遅延もあり得ると書かれています。登録直後の画面で自社DBの行を前提にすると、行がまだ無い瞬間に500エラーになります。初回アクセス時にuserIdで行を作るupsertを併用し、Webhookは補正用と割り切る設計が安全です。

Clerk認証の日本語対応:localizationで訳せる範囲と英語のまま残る画面

「Clerk 日本語」で調べる人が多いのは、初期状態の画面がすべて英語だからです。対応方法と限界を分けて押さえます。

jaJPによる日本語表示の設定とexperimental扱いの運用上の注意

Localizationのドキュメントには日本語(ja-JP)が含まれ、@clerk/localizationsからjaJPを読み込んで渡すだけで切り替わります。

import { jaJP } from '@clerk/localizations'

<ClerkProvider localization={jaJP}>
  {children}
</ClerkProvider>

同じページで、この機能はexperimentalで予告なく変わり得ると明記されています。文言の一部だけ差し替えたい場合はjaJPを展開してキーを上書きできますが、SDK更新のたびに表示を目視で確かめる手順をリリース作業に入れておきます。

Account Portalとダッシュボードは英語のまま:日本向け案件の影響

翻訳が効くのはアプリに埋め込んだClerkコンポーネントの文言だけで、ClerkがホストするAccount Portalは英語のままと公式に書かれています。サインイン画面をホスト側に任せる構成だと、日本語の利用者に英語画面が出ます。

回避策は、SignInコンポーネントを自社ドメインのページへ埋め込み、すべての導線をそこへ寄せることです。管理者が触るダッシュボードも英語なので、運用担当が英語UIを扱えるかも導入前に確認しておきます。

Clerk認証の料金:MRU課金の数え方とHobby・Pro・Businessの境目

Clerkの課金単位は、一般的なMAUではなくMRU(Monthly Retained User)です。料金は公式の料金ページの2026年10月時点の値で整理します。

MRUの定義と1アプリ5万人の無料枠、超過単価0.02ドルの段階制

MRUは、サインアップから24時間以上たってから月内に再訪したユーザーだけを数えます。登録した日にしか使わなかった人は課金対象になりません。どのプランも1アプリあたり50,000MRUまで含まれ、超過分はPro・Businessで段階制の単価がかかります。

プラン 月額(月払い/年払い) 含まれるMRU 超過単価(1MRUあたり月額)
Hobby 無料 50,000 超過時はProへ移行
Pro 25ドル/20ドル 50,000 人数帯別の段階制(単価は表の直後)
Business 300ドル/250ドル 50,000 Proと同じ段階制
Enterprise 個別見積(年払い) 個別 個別

超過単価は、5万超〜10万:0.02ドル、10万超〜100万:0.018ドルです。たとえば月間の再訪ユーザーが8万人なら、Proの超過3万人×0.02ドルで600ドルが基本料に加わる計算です。

MFA不可とセッション7日固定:Hobbyで本番運用できない条件

無料のHobbyは人数枠こそProと同じですが、MFAが使えず、セッション期間は7日固定です。Clerkのブランド表示も外せません。管理画面を持つ業務アプリや、社内規程で多要素認証が必須の案件は、最初からPro以上で見積もります。

B2B向けに顧客企業ごとのSAML接続を張る場合、Pro・Businessに含まれるのは1接続までで、2〜15接続目は1接続あたり月75ドルです。SOC2レポートの提出を求められる取引ならBusinessが必要になります。

ClerkとAuth0・Auth.jsの選び分け:採用すべき条件と見送る場面

認証の外部化は後から移すのが難しい判断です。ここでは受託開発の現場で使っている判定の条件を、そのまま言い切ります。

Clerkを採用すべき条件:Next.jsのB2Cアプリで会員機能を短期で出す

採用するのは、フロントがNext.jsかReactで、利用者が一般消費者中心、SSO接続は0〜1本、という3条件がそろう案件です。この場合、画面部品とセッション更新を自作する工数がまるごと消え、月の再訪5万人までは無料で検証できます。

同じ顧客ID基盤でもAuth0はMAU課金で、規模が増えたときの金額の伸び方が異なります。両者の差はAuth0の料金とMAU課金の増え方と並べて比べてください。

Clerkを見送る場面:非React構成・SAML多数接続・全画面日本語化

見送るのは次のどれかに当てはまる案件です。LaravelのBladeやSpring MVCなどサーバー側で画面を描画し、Reactの部品を使わない構成。顧客ごとのSAML接続が10本を超え、接続料だけで月675ドルを超えるB2B。ホスト画面まで日本語が必須の案件です。

ユーザー情報を自社DBに持ち続けたいなら、OSSのAuth.jsのv5導入手順やbetter-authの使い方、DBの行レベル権限と組むならSupabase Authの設計判断が候補です。既存会員DBからの移行や複数サービスの統合ログインを含めて設計したい場合は、認証基盤・ID管理システム開発として要件整理から相談を受けています。

Clerk認証の導入前によくある質問:無料枠・日本語対応・移行と選定

Clerkの導入検討でよく出る質問に、2026年10月時点の公式情報をもとに答えます。

Clerkは無料でどこまで使えますか?

Hobbyプランは無料で、1アプリあたり50,000MRUまで使えます。MRUはサインアップから24時間以上たって再訪したユーザーだけを数えるため、登録だけで離脱した人は含まれません。ただしMFAは使えず、セッション期間は7日固定、Clerkのブランド表示も残ります。本番の業務アプリならPro(月25ドル、年払いなら月20ドル)からの見積もりが現実的です。

Clerkのサインイン画面は日本語にできますか?

アプリに埋め込むコンポーネントは、@clerk/localizationsのjaJPをClerkProviderに渡せば日本語になります。ただし機能はexperimental扱いで、ClerkがホストするAccount Portalは英語のままです。日本語の利用者に英語画面を見せたくない場合は、サインイン画面を自社ページに埋め込む構成にします。

authMiddlewareを使った古い記事のコードは動きますか?

動かない前提で読み替えてください。現行の@clerk/nextjs 7系ではclerkMiddleware()を使い、Next.js 16ではproxy.tsに置きます。パス単位で保護するcreateRouteMatcher()も非推奨になり、ページやRoute Handlerの中でawait auth()を呼んで判定する書き方が推奨です。

ClerkとAuth0はどちらを選べばよいですか?

Next.jsかReactが主体で、一般消費者向けの会員機能を短期で出すならClerkが向いています。サーバー側で画面を描画する従来型のWebアプリ、エンタープライズ向けのSAML接続を多数張る構成、Actionsでログイン処理に独自の手順を差し込みたい場合はAuth0の方が適した選択肢です。課金単位もClerkはMRU、Auth0はMAUと異なります。

Clerkのユーザー情報を自社データベースに保存できますか?

できます。user.createdなどのWebhookを受け、verifyWebhook()で署名を確かめてから自社DBへupsertします。配信は保証されず遅延もあるため、登録直後の処理は自社DBの行を前提にしないでください。必要な属性がセッショントークンのクレームに収まるなら、DBへ写さずトークンから読む方が整合性を保てます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウド(IDCフロンティア)不正アクセス・ランサムウェア:影響先・復旧・データは戻るか
  2. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順
  3. 2026.10.09 テックブログ ユニリタの不正アクセス:SaaS文書管理から漏れた顧客の認証情報と回す手順
  4. 2026.10.08 テックブログ 大阪公立大学のランサムウェア被害と仮想化基盤の停止|全授業休講に至った経緯とバックアップを守る設定
  5. 2026.10.10 コラム 介護保険法改正とは?令和8年法律第51号の施行日と介護システムの改修項目

RELATED POSTS 関連記事

目次