Next.js + Clerkで認証機能を作ってみた
Next.js
2024-09-16
はじめに
最近「Clerk」という認証ライブラリを知ったので、実際に触ってみた感想やNext.jsに組み込む方法をまとめる。
Clerkとは
ClerkはNextAuth.js などと同じような認証ライブラリです。
メールアドレス・パスワード認証を始め、SNS認証、多要素認証(MFA)などの機能を数行のコードで実装でき、UIコンポーネントも用意してくれているので、簡単に認証機能を構築することが可能。
Next.js以外のRemixやAstro、React Nativeなどネイティブアプリに利用することができる。
Clerk側のセットアップ
Clerkを利用するにはアカウント登録が必要なので、まず登録を行う。
Clerkアプリケーションの作成
続いて、Clerkアプリケーションを作成する。
フォームに入力した内容を元に、UIイメージを確認することができる。
入力させたい項目や、SNS認証として利用したいプロバイダーをここで選択する
これでClerk側のセットアップは完了!
Next.js側のセットアップ
Clerkのインストール
yarn add @clerk/nextjs
環境変数の設定
Clerkアプリケーション作成後に環境変数が発行されるので .env.local
に記述する
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test...
CLERK_SECRET_KEY=sk_test...
ミドルウェアの作成
middleware.ts
ファイルを作成し、下記のコード記述する
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
// Always run for API routes
"/(api|trpc)(.*)",
],
};
clerkMiddleware
に保護したいルートを指定することで、認証済みでないとアクセスできないページを作れる
細かいルート設定は以下のURLを参照
https://clerk.com/docs/references/nextjs/clerk-middleware
ClerkProviderの設定
app/layout.tsx
でClerkProvider
コンポーネントを追加して、どのページからでも認証済みのユーザー情報などの認証情報にアクセスできるようにする
import { ClerkProvider } from '@clerk/nextjs'
import './globals.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<ClerkProvider>
<html lang="en">
<body>
{children}
</body>
</html>
</ClerkProvider>
)
}
サインイン・サインアップ画面の作成
サインアップ画面
app/sign-up/[[...sign-up]]/page.tsx
のディレクトリ、ファイルを作成し、ClerkのSignUp
コンポーネントを表示することで、アプリケーション作成時に設定した登録画面のUIを表示できる
import { SignUp } from "@clerk/nextjs";
const SignUpPage = () => {
return (
<div className="h-[calc(100vh-96px)] flex items-center justify-center">
<SignUp />
</div>
);
}
export default SignUpPage;
サインイン画面
app/sign-in/[[...sign-in]]/page.tsx
のディレクトリ、ファイルを作成し、ClerkのSignIn
コンポーネントを表示する
import { SignIn } from "@clerk/nextjs";
const SingInPage =() => {
return (
<div className="h-[calc(100vh-96px)] flex items-center justify-center">
<SignIn />
</div>
);
}
export default SingInPage;
認証情報
サインインやサインアップを行うと、Clerkは認証ユーザの情報をJWTベースでセッション管理し、プラウザのCookieに付与する。
認証中のユーザー情報はauth()
ヘルパで取得できるため、認証ユーザーにのみページのUIを変更したい場合の判別データとして使える。
バックエンドリクエストの保護
バックエンドにNext.jsを利用している場合は、セットアップで作成したmiddleware.ts
のclerkMiddleware
に保護したいAPIのパスを指定することで、バックエンドリクエストを保護できる。
バックエンドにNext.js以外を利用している場合は、Clerk SDKを利用する
下記の言語/フレームワークはSDKが提供されている。
- Go
- Node.js
- Ruby/Rails
- JavaScript
- Expo
- iOS
- React
- Remix
- Astro
提供されていない言語/フレームワークを使用している場合でもSDKを自作するためのドキュメントが用意されているため、作ることは可能
https://clerk.com/docs/references/sdk/overview
まとめ
自分は、フロントエンドの認証ライブラリを触ったことないためClerkを他のライブラリと比較することができないが、UIコンポーネントやダッシュボードが充実しているため、ユーザー情報の管理や認証フローの実装が簡単に行える点が良い。
また、設計が柔軟なため、フロントエンドからバックエンドまで幅広いカスタマイズに対応しているので採用しやすいライブラリだと思う。