using-authentication
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWorking with Authentication
认证功能实践
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
使用Better Auth实现客户端与服务端认证,涵盖会话访问、受保护路由、登录/登出以及用户数据获取。
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: in Fullstack Recipes
using-authentication - URL: https://fullstackrecipes.com/recipes/using-authentication
使用Better Auth实现客户端与服务端认证,涵盖会话访问、受保护路由、登录/登出以及用户数据获取。
参考:
- 资源:Fullstack Recipes中的
using-authentication - 链接:https://fullstackrecipes.com/recipes/using-authentication
Client-Side Authentication
客户端认证
Use the auth client hooks in React components:
tsx
"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>
);
}在React组件中使用认证客户端钩子:
tsx
"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:
typescript
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>;
}typescript
// 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...
}在服务端组件与API路由中获取会话:
typescript
import { auth } from "@/lib/auth/server";
import { headers } from "next/headers";
// 在服务端组件中
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>;
}typescript
// 在API路由中
export async function POST(request: Request) {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return new Response("Unauthorized", { status: 401 });
}
// 使用session.user.id进行查询...
}Protected Pages Pattern
受保护页面实现模式
Redirect unauthenticated users:
tsx
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} />;
}将未认证用户重定向:
tsx
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:
tsx
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 />;
}将已认证用户从认证页面重定向:
tsx
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"); // 已登录
}
return <SignIn />;
}Signing In
登录
typescript
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",
});typescript
import { signIn } from "@/lib/auth/client";
// 邮箱/密码登录
await signIn.email({
email: "user@example.com",
password: "password",
callbackURL: "/chats",
});
// 社交账号登录
await signIn.social({
provider: "google",
callbackURL: "/chats",
});Signing Up
注册
typescript
import { signUp } from "@/lib/auth/client";
await signUp.email({
email: "user@example.com",
password: "password",
name: "John Doe",
callbackURL: "/verify-email",
});typescript
import { signUp } from "@/lib/auth/client";
await signUp.email({
email: "user@example.com",
password: "password",
name: "John Doe",
callbackURL: "/verify-email",
});Signing Out
登出
typescript
import { signOut } from "@/lib/auth/client";
await signOut({
fetchOptions: {
onSuccess: () => {
router.push("/");
},
},
});typescript
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:
tsx
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} />;
}在受保护页面中,验证会话后获取用户专属数据:
tsx
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} />;
}