0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Clerk × Next.js 16 で認証を最速実装する — Google OAuth + 日本語化まで10分

0
Posted at

はじめに

個人開発のWebサービスで認証機能が必要になったとき、選択肢は多数あります:

  • NextAuth.js(Auth.js)
  • Firebase Authentication
  • Supabase Auth
  • Clerk

今回はClerkを選びました。理由は「最も少ないコードで、最も多くの機能が手に入る」からです。

なぜ Clerk か

比較項目 Clerk NextAuth.js Firebase Auth
導入コード量 3ファイル 10ファイル以上 5ファイル以上
UI 組み込み済み 自作 自作
Google OAuth ダッシュボードでON Provider設定 + Callback Console設定
日本語化 jaJP ロケール 自作 自作
ユーザー管理画面 ダッシュボード なし Firebase Console
無料枠 10,000 MAU 無制限
料金 $0〜$25/月 無料 無料〜

10,000 MAU無料は個人開発には十分すぎます。UIが組み込み済みなので、サインイン/サインアップ画面を自作する必要がありません。

実装手順

1. インストール(30秒)

npm install @clerk/nextjs @clerk/localizations

2. 環境変数(1分)

Clerk ダッシュボードからキーを取得して .env.local に設定:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard

3. layout.tsx に Provider 追加(2分)

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

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

localization={jaJP} を渡すだけで、サインイン画面・エラーメッセージがすべて日本語になります。

4. Middleware で認証チェック(3分)

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

const isPublicRoute = createRouteMatcher([
    "/",
    "/features",
    "/guide",
    "/faq",
    "/terms",
    "/privacy",
    "/contact",
    "/sign-in(.*)",
    "/sign-up(.*)",
    "/api/webhooks(.*)",
    "/api/health",
]);

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

export const config = {
    matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};

これだけで全ページに認証がかかります。 公開ページだけを明示的にリストアップし、それ以外は自動で protect() が適用されます。

5. サインインページ(2分)

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

export default function Page() {
    return (
        <div className="flex justify-center items-center min-h-screen">
            <SignIn />
        </div>
    );
}
// app/sign-up/[[...sign-up]]/page.tsx
import { SignUp } from "@clerk/nextjs";

export default function Page() {
    return (
        <div className="flex justify-center items-center min-h-screen">
            <SignUp />
        </div>
    );
}

UIは完全にClerkが提供。 メールアドレス入力、パスワード設定、メール認証、Google OAuthボタンがすべて含まれています。

完了!

以上の5ステップで認証が動きます。実作業時間は10分以下です。

API Route での認証

// app/api/invoices/route.ts
import { auth } from "@clerk/nextjs/server";

export async function GET() {
    const { userId } = await auth();
    if (!userId) {
        return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // userId を使ってDBからデータ取得
    const invoices = await prisma.invoice.findMany({
        where: { user: { clerkId: userId } },
    });
    return NextResponse.json(invoices);
}

auth() を呼ぶだけでユーザーIDが取れます。

Google OAuth の有効化

  1. Clerk ダッシュボード → Configure → SSO Connections → Google をON
  2. Google Cloud Console でOAuth同意画面を設定
  3. Client ID / Client Secret を Clerk に登録

Clerk側は「Google」のトグルをONにするだけ。Google Cloud Console側の設定は必要ですが、Clerkのドキュメントに手順が書かれています。

DB連携パターン: getOrCreateUser

ClerkはユーザーデータをClerk側で管理しますが、アプリ固有のデータ(クレジット残高、請求書など)はDBに保存する必要があります。

初回アクセス時にDB作成する方式が最もシンプルです:

// lib/auth.ts

export async function getOrCreateUser() {
    const { userId } = await auth();
    if (!userId) throw new Error("Unauthorized");

    let user = await prisma.user.findUnique({
        where: { clerkId: userId },
    });

    if (!user) {
        // Clerkからメールアドレスを取得
        const clerkUser = await clerkClient.users.getUser(userId);
        const email = clerkUser.emailAddresses[0]?.emailAddress;

        // トランザクションでユーザー作成 + 初期クレジット付与
        user = await prisma.$transaction(async (tx) => {
            const newUser = await tx.user.create({
                data: {
                    clerkId: userId,
                    email,
                    creditBalance: 3, // 無料お試し3回分
                },
            });
            await tx.creditTransaction.create({
                data: {
                    userId: newUser.id,
                    amount: 3,
                    type: "initial_grant",
                    description: "新規登録特典",
                },
            });
            return newUser;
        });
    }

    return user;
}

本番環境への移行

ClerkにはDevelopmentProductionの2つのインスタンスがあります。本番移行時のチェックリスト:

  1. Clerk ダッシュボードで Production instance を作成
  2. カスタムドメイン(例: clerk.toruca.app)のDNS設定
  3. 環境変数を Production キーに差し替え
  4. Google OAuth の Authorized redirect URIs を本番ドメインに更新
  5. Google OAuth 同意画面を「本番環境」に切り替え

まとめ

  • npm install → Provider → Middleware → サインインページ の4ステップで完了
  • jaJP ロケールで日本語化が1行
  • Google OAuthはダッシュボードでトグルON
  • auth() でどこでもユーザーIDが取れる
  • 10,000 MAU無料で個人開発には十分

認証はサービスの根幹なので、自前実装よりも実績のあるサービスに任せるのが安全です。


この構成で認証を実装したサービス: トルカ 振込アシスト — 請求書からAIで全銀フォーマットの振込データを自動生成

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?