Next.jsにClerkを設定する簡易手順
はじめに
- Next.js のプロジェクトに Clerk を設定する手順を紹介します。
- 作業コードは以下にあります。
Clerkとは
- Clerk とは、認証機能を提供するサービスです。
- Clerk を利用することで、 Next.js で認証機能を簡単に実装できます。
以降では実際に、Next.js で Clerk を設定していきます。
Clerkのアカウント作成
Clerk のアカウントを作成します。Clerk へのログインは、GitHub アカウントで行えます。
サイトにアクセスします。
「Sign in」をクリックします。
「Continue with GitHub」で自身の GitHub アカウントでログインします。
「Authorize clerk.inc」をクリックします。
このページまで来れば、Clerk のアカウント作成は完了です。
Clerkでアプリケーション作成
続いて、Clerk 上でアプリケーションを作成します。
- アプリケーション名を入力します。(今回は「nextjs-clerk-sample」と入力します)
- 認証方法を設定します。(今回は「Google」を選択します)
- 「Create Application」をクリックし、アプリケーションを作成します。
アプリケーションの作成が完了しました。
Next.jsプロジェクトの新規作成
作業するプロジェクトを新規に作成していきます。
長いので、折りたたんでおきます。
新規プロジェクト作成と初期環境構築の手順詳細
$ pnpm create next-app@latest nextjs-clerk-simple-sample --typescript --eslint --import-alias "@/*" --src-dir --use-pnpm --tailwind --app
$ cd nextjs-clerk-simple-sample
以下の通り不要な設定を削除し、プロジェクトの初期環境を構築します。
$ mkdir src/styles
$ mv src/app/globals.css src/styles/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
export default function Home() {
return (
<main className="text-lg">
テストページ
</main>
)
}
import '@/styles/globals.css'
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<body className="">{children}</body>
</html>
);
}
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
plugins: [],
};
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
+ "baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
コミットします。
$ pnpm build
$ git add .
$ git commit -m "新規にプロジェクトを作成し, 作業環境を構築"
Clerkをインストール
Next.js で Clerk が提供する SDK を利用するために、Clerk のパッケージをインストールします。
$ pnpm add @clerk/nextjs
環境変数を設定
環境変数を .env.local
に設定します。APIKEY はダッシュボードから取得します。
APIKEY を .env.local
に設定します。
$ touch .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_publishable_key
CLERK_SECRET_KEY=your_secret_key
ClerkProviderの設定
どこからでもセッション、認証済みのユーザー情報などの認証情報にアクセスできるように、<ClerkProvider>
コンポーネントを設定します。
layout.tsx
に <ClerkProvider>
を設定します。
+import { ClerkProvider } from "@clerk/nextjs";
import "./globals.css";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
+ <ClerkProvider>
<html lang="ja">
<body className="bg-white">{children}</body>
</html>
+ </ClerkProvider>
);
}
アプリケーション全体を保護
middleware.ts
でアプリケーションのどの部分を保護するか設定できます。
matcher
で保護したいパスを指定します。今回はアプリケーション全体を保護します。
$ touch src/middleware.ts
import { authMiddleware } from "@clerk/nextjs";
export default authMiddleware();
export const config = {
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};
動作確認
ローカルで実行します。
$ pnpm dev
ブラウザで http://localhost:3000/ にアクセスします。すると、想定どおり、ログインページにリダイレクトされました。Continue with Google をクリックすると、Google のログイン画面に遷移します。
Google アカウントにログインします。
ユーザー名を入力するとアカウントが作成されます。
ログインが完了して、ページが表示されます。
コミットします。
$ pnpm build
$ git add .
$ git commit -m "Clerkの設定を実施"
アカウント一覧を確認
Clerk のダッシュボードから、アカウント一覧を確認できます。
- Users をクリックします。
- ユーザー一覧に、先ほど Google 認証したユーザーが表示されます。
ソーシャルログインの追加
Clerk では以下のソーシャルログインが利用できます。日本でよく使われる LINE も含まれています。
- TikTok
- Discord
- Twitch
- GitHub
- GitLab
- HubSpot
- Atlassian
- Bitbucket
- Dropbox
- Microsoft
- Notion
- Apple
- LINE
- Coinbase
- Spotify
- Box
- Xero
- Slack
- Linear
ソーシャルログインの追加は簡単にできます。
ダッシュボードのメニューからソーシャルログインを追加します。
- User & Authentication をクリック
- Social Connection をクリック
- 追加したいソーシャルログインをクリック
今回は facebook を追加します。
追加できました。
ログインページに facebook のボタンが追加されました。
Social Connection から facebook での認証は無効化しておきます。
ユーザボタンの追加
Clerk では、ユーザーのログイン状態に応じて、ユーザー名やログインボタンを表示できます。現時点では英語しか対応されていませんが、<UserButton />
を利用することで、簡単に実装できます。
以下を実装します。
-
middleware.ts
を修正し、http://localhost:3000/
に認証していなくてもアクセスできるようにする。 - 認証されている場合は、認証されてたユーザーに合わせたユーザーボタンを表示、認証されていない場合は、ログインボタンを表示します。
まず、middleware.ts
に認証していなくてもアクセスできるように publicRoutes
を追加します。publicRoutes
についてはこちらを参照ください。
import { authMiddleware } from "@clerk/nextjs";
export default authMiddleware(
+ {
+ publicRoutes: ["/"],
+ }
);
export const config = {
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};
そして、pages.tsx
を修正します。
-
<SignedIn />
は、認証されている場合に、children
が表示されるコンポーネントです。 -
<UserButton />
は、認証されているユーザーに合わせたユーザーボタンを表示するコンポーネントです。 -
<SignedOut />
は、認証されていない場合に、children
が表示されるコンポーネントです。 -
<SignInButton />
は、ログインボタンを表示するコンポーネントです。
+import { SignInButton, SignedIn, SignedOut, UserButton } from "@clerk/nextjs";
export default function Home() {
return (
+ <>
+ <header
+ style={{
+ display: "flex",
+ justifyContent: "space-between",
+ padding: 20,
+ }}
+ >
+ <h1>My App</h1>
+ <SignedIn>
+ {/* Mount the UserButton component */}
+ <UserButton afterSignOutUrl="/" />
+ </SignedIn>
+ <SignedOut>
+ {/* Signed out users get sign in button */}
+ <SignInButton />
+ </SignedOut>
+ </header>
<main className="text-lg">テストページ</main>
+ </>
);
}
それでは、実行してみます。
$ pnpm dev
http://localhost:3000/
にアクセスすると、ログインボタンが表示されます。ログインボタンをクリックすると、ログインページに遷移します。
ログインします。
ログイン後にユーザーボタンを表示されました。
クリックすると、ユーザー情報が表示されます。「Manage account」をクリックします。
アカウント管理画面がポップアウトされます。英語ですが、このページにはアカウント情報の詳細が表示されます。
「Sign out」をクリックするとログアウトします。
ログアウト後には、ログインボタンが表示されます。
コミットします。
$ pnpm build
$ git add .
$ git commit -m "ユーザーボタンを追加"
ユーザー情報の取得
currentUser()
でユーザー情報の簡単に取得できます。取得できるユーザー情報は以下を参照ください。
項目 | タイプ | 説明ion |
---|---|---|
externalId | string | 外部システムで使用するユーザーのID。インスタンス全体で一意です。 |
emailAddress[] | string | ユーザーの電子メールアドレス。インスタンス全体で一意であす。最初の電子メールアドレスがユーザーのプライマリ電子メールアドレスとして設定されます。 |
phoneNumber[] | string | ユーザーの電話番号。インスタンス全体で一意です。最初の電話番号がユーザーのプライマリ電話番号として設定されます。 |
username | string | ユーザーが設定したユーザー名。インスタンス全体で一意です。 |
password | string | ユーザーに与える平文のパスワード。 |
firstName | string | ユーザーの名。 |
lastName | string | ユーザーの姓。 |
publicMetadata | Record<string, unknown> | ユーザーに保存されたメタデータで、フロントエンドとバックエンドの両方のAPIで表示されます。 |
privateMetadata | Record<string, unknown> | ユーザーに保存されたメタデータで、バックエンドAPIのみで表示されます。 |
unsafeMetadata | Record<string, unknown> | ユーザーに保存されたメタデータで、フロントエンドとバックエンドの両方のAPIで表示されます。 |
詳細は以下を参照ください。
ログインしている場合は、ユーザー情報を表示するようにします。
- ログインしている場合は、名前を表示します。
- ログインしている場合は、
privateMeatadata
を表示します。
import {
SignInButton,
SignedIn,
SignedOut,
UserButton,
+ currentUser,
} from "@clerk/nextjs";
-export default function Home() {
+export default async function Home() {
+ const user = await currentUser();
return (
<>
<header
style={{
display: "flex",
justifyContent: "space-between",
padding: 20,
}}
>
<h1>My App</h1>
<SignedIn>
{/* Mount the UserButton component */}
<UserButton afterSignOutUrl="/" />
</SignedIn>
<SignedOut>
{/* Signed out users get sign in button */}
<SignInButton />
</SignedOut>
</header>
<main className="text-lg">
- テストページ
+ <SignedIn><div>{user?.firstName}</div></SignedIn>
+ <SignedIn><div>{JSON.stringify(user?.privateMetadata)}</div></SignedIn>
</main>
</>
);
}
privateMetadata
とはユーザーが自由に設定できるメタデータです。privateMetadata
は、ユーザーのプライバシーを保護するために、フロントエンドからはアクセスできません。バックエンドからはアクセスできます。
privateMetadata
を設定します。まず Clerk の管理コンソールにアクセスします。ユーザー一覧からユーザーを選択します。
Metadata のセクションまでスクロールします。
「Edit」をクリックし、Private
を編集することで、privateMetadata
を設定できます。
ローカルサーバで動作確認をします。
$ pnpm dev
ログインすると、ユーザーの名前と先程設定した privateMetadata
が表示されます。
コミットします。
$ pnpm build
$ git add .
$ git commit -m "currentUserを追加"
まとめ
- Next.js のプロジェクトに Clerk を設定する手順を紹介しました。
- 作業コードは以下にあります。
Discussion