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>
  );
}
服务端会话

在服务器组件和 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("/") },
});

参考资料

评论

支持 Markdown