From andrelandgraf-fullstackrecipes
Read sessions client- and server-side, guard routes, and run sign in/up/out with Better Auth. Use when gating pages/APIs on auth or wiring auth flows.
How this skill is triggered — by the user, by Claude, or both
Slash command
/andrelandgraf-fullstackrecipes:authentication-best-practicesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Read sessions, protect routes, and run sign in/up/out with Better Auth.
Read sessions, protect routes, and run sign in/up/out with Better Auth.
Complete these setup recipes first:
Use the auth client hooks from @/lib/auth/client in client 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>
);
}
In Server Components and API routes, call auth.api.getSession with the request headers.
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...
Redirect unauthenticated users away from protected pages, and 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 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 />;
}
After validating the session, fetch user-specific data in parallel.
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("/") },
});
npx claudepluginhub joshuarweaver/cascade-code-general-misc-3 --plugin andrelandgraf-fullstackrecipesImplements complete Next.js authentication with Auth.js: OAuth providers (GitHub/Google), credentials login, Prisma adapter, session management (JWT/DB), middleware-protected routes, RBAC, and login forms.
Implements authentication in Next.js using Auth.js v5 with session handling, middleware guards, server-side session access, and OAuth integration.
Better Auth in TypeScript — setting up the auth instance, picking adapters, wiring framework route handlers, configuring sessions and cookies, adding plugins (2FA, organization, admin, magicLink, JWT), or porting from NextAuth/Auth.js, Clerk, Auth0, or Supabase Auth. Covers Next.js, SvelteKit, Hono, Express, Nuxt, Astro, and React/Vue/Svelte clients. Trigger when writing, reviewing, or migrating Better Auth code — and even when the user doesn't explicitly mention Better Auth but is working on TypeScript authentication, session cookies, OAuth providers, or auth-library migration. Contains 42 rules organized by impact across 8 categories.