mcpField
A
authentication-best-practices

authentication-best-practices

github.com/andrelandgrafセキュリティ2396 回インストール20 週間前に更新
リポジトリ

authentication-best-practices について

Better Auth を使ってセッション管理と認証フローを実装する開発者向けレシピです。クライアント側とサーバー側のセッション取得、ルート保護、サインイン・登録・サインアウトの方法を説明します。

主な機能

  1. 01クライアント側のセッションフック
  2. 02サーバー側のセッション取得
  3. 03認証ルートの保護
  4. 04サインイン・登録・サインアウト
  5. 05ユーザーデータの並列取得

活用シーン

  1. 01クライアントコンポーネントでのセッション確認
  2. 02未認証のルートリクエストの拒否
  3. 03セッション検証後のユーザーデータ読み込み

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill authentication-best-practices

インストール後、Claude Code で/authentication-best-practicesを入力して読み込まれたか確認します。

詳細

認証のベストプラクティス

Better Auth を使って、セッションの読み取り、ルートの保護、サインイン/サインアップ/サインアウトを行います。

前提条件

まず、次のセットアップ手順を完了してください。

  • Better Auth のセットアップ
クライアント側のセッション

クライアントコンポーネントでは、@/lib/auth/client の認証クライアントフックを使用します。

"use client";

import { useSession, signOut } from "@/lib/auth/client";

export function UserMenu() {
  const { data: session, isPending } = useSession();

  if (isPending) return <div>Loading...</div>;
  if (!session) return <a href="/sign-in">Sign In</a>;

  return (
    <div>
      <span>{session.user.name}</span>
      <button onClick={() => signOut()}>Sign Out</button>
    </div>
  );
}
サーバー側のセッション

Server Components と API ルートでは、リクエストの headers を指定して auth.api.getSession を呼び出します。

import { auth } from "@/lib/auth/server";
import { headers } from "next/headers";

const session = await auth.api.getSession({ headers: await headers() });

if (!session) {
  return new Response("Unauthorized", { status: 401 });
}

// session.user.id for queries...
ルートの保護

未認証ユーザーは保護されたページからリダイレクトし、認証済みユーザーは認証ページからリダイレクトします。

import { redirect } from "next/navigation";
import { headers } from "next/headers";
import { auth } from "@/lib/auth/server";

export default async function ProtectedPage() {
  const session = await auth.api.getSession({ headers: await headers() });
  if (!session) redirect("/sign-in");
  return <Dashboard user={session.user} />;
}

export default async function SignInPage() {
  const session = await auth.api.getSession({ headers: await headers() });
  if (session) redirect("/chats");
  return <SignIn />;
}

セッションを検証した後、ユーザー固有のデータを並列で取得します。

const [chats, profile] = await Promise.all([
  getUserChats(session.user.id),
  getUserProfile(session.user.id),
]);
サインイン/サインアップ/サインアウト
import { signIn, signUp, signOut } from "@/lib/auth/client";

await signIn.email({ email, password, callbackURL: "/chats" });
await signIn.social({ provider: "google", callbackURL: "/chats" });

await signUp.email({ email, password, name, callbackURL: "/verify-email" });

await signOut({
  fetchOptions: { onSuccess: () => router.push("/") },
});

参考資料

コメント