关于 using-authentication
Fullstack Recipes 中的技能,介绍开发者如何使用 Better Auth 实现客户端和服务端身份验证,涵盖会话、路由保护、登录退出及用户数据获取。
主要功能
- 01客户端会话钩子
- 02服务端会话访问
- 03受保护路由模式
- 04电子邮件登录与注册
- 05获取用户专属数据
适用场景
- 01显示已登录用户的会话
- 02为页面和 API 路由设置身份验证
- 03构建登录与注册流程
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ andrelandgraf/ fullstackrecipes --skill using-authentication安装后在 Claude Code 中输入/using-authentication确认已加载。
详细介绍
使用身份验证
使用 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>
);
}
服务器端会话访问
在 Server Components 和 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: "[email protected]",
password: "password",
callbackURL: "/chats",
});
// Social provider
await signIn.social({
provider: "google",
callbackURL: "/chats",
});
注册
import { signUp } from "@/lib/auth/client";
await signUp.email({
email: "[email protected]",
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} />;
}
参考资料
评论
支持 Markdown