using-authentication
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o using-authentication.zip https://jpskill.com/download/22384.zip && unzip -o using-authentication.zip && rm using-authentication.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/22384.zip -OutFile "$d\using-authentication.zip"; Expand-Archive "$d\using-authentication.zip" -DestinationPath $d -Force; ri "$d\using-authentication.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
using-authentication.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
using-authenticationフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
認証の操作
クライアントサイドとサーバーサイドの認証には Better Auth を使用します。セッションアクセス、保護されたルート、サインイン/サインアウト、ユーザーデータの取得をカバーしています。
認証の操作を実装する
クライアントサイドとサーバーサイドの認証には Better Auth を使用します。セッションアクセス、保護されたルート、サインイン/サインアウト、ユーザーデータの取得をカバーしています。
参照:
- リソース: Fullstack Recipes の
using-authentication - URL: https://fullstackrecipes.com/recipes/using-authentication
クライアントサイド認証
React コンポーネントで認証クライアントフックを使用します。
"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>
);
}
サーバーサイドセッションアクセス
サーバーコンポーネントと API ルートでセッションを取得します。
import { auth } from "@/lib/auth/server";
import { headers } from "next/headers";
// In a Server Component
export default async function Page() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return <div>Not signed in</div>;
}
return <div>Hello, {session.user.name}</div>;
}
// In an API route
export async function POST(request: Request) {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return new Response("Unauthorized", { status: 401 });
}
// Use 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} />;
}
認証ページのパターン
認証済みユーザーを認証ページからリダイレクトします。
import { redirect } from "next/navigation";
import { headers } from "next/headers";
import { auth } from "@/lib/auth/server";
export default async function SignInPage() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (session) {
redirect("/chats"); // Already signed in
}
return <SignIn />;
}
サインイン
import { signIn } from "@/lib/auth/client";
// Email/password
await signIn.email({
email: "user@example.com",
password: "password",
callbackURL: "/chats",
});
// Social provider
await signIn.social({
provider: "google",
callbackURL: "/chats",
});
サインアップ
import { signUp } from "@/lib/auth/client";
await signUp.email({
email: "user@example.com",
password: "password",
name: "John Doe",
callbackURL: "/verify-email",
});
サインアウト
import { signOut } from "@/lib/auth/client";
await signOut({
fetchOptions: {
onSuccess: () => {
router.push("/");
},
},
});
認証後のユーザーデータの取得
保護されたページでは、セッションを検証した後にユーザー固有のデータを取得します。
export default async function DashboardPage() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
redirect("/sign-in");
}
const [chats, profile] = await Promise.all([
getUserChats(session.user.id),
getUserProfile(session.user.id),
]);
return <Dashboard chats={chats} profile={profile} />;
}
参考文献
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Working with Authentication
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
Implement Working with Authentication
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
See:
- Resource:
using-authenticationin Fullstack Recipes - URL: https://fullstackrecipes.com/recipes/using-authentication
Client-Side Authentication
Use the auth client hooks in React components:
"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-Side Session Access
Get the session in Server Components and API routes:
import { auth } from "@/lib/auth/server";
import { headers } from "next/headers";
// In a Server Component
export default async function Page() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return <div>Not signed in</div>;
}
return <div>Hello, {session.user.name}</div>;
}
// In an API route
export async function POST(request: Request) {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return new Response("Unauthorized", { status: 401 });
}
// Use session.user.id for queries...
}
Protected Pages Pattern
Redirect unauthenticated users:
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} />;
}
Auth Pages Pattern
Redirect authenticated users away from auth pages:
import { redirect } from "next/navigation";
import { headers } from "next/headers";
import { auth } from "@/lib/auth/server";
export default async function SignInPage() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (session) {
redirect("/chats"); // Already signed in
}
return <SignIn />;
}
Signing In
import { signIn } from "@/lib/auth/client";
// Email/password
await signIn.email({
email: "user@example.com",
password: "password",
callbackURL: "/chats",
});
// Social provider
await signIn.social({
provider: "google",
callbackURL: "/chats",
});
Signing Up
import { signUp } from "@/lib/auth/client";
await signUp.email({
email: "user@example.com",
password: "password",
name: "John Doe",
callbackURL: "/verify-email",
});
Signing Out
import { signOut } from "@/lib/auth/client";
await signOut({
fetchOptions: {
onSuccess: () => {
router.push("/");
},
},
});
Fetching User Data After Auth
In protected pages, fetch user-specific data after validating the session:
export default async function DashboardPage() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
redirect("/sign-in");
}
const [chats, profile] = await Promise.all([
getUserChats(session.user.id),
getUserProfile(session.user.id),
]);
return <Dashboard chats={chats} profile={profile} />;
}