using-authentication
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
Best use case
using-authentication is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
Teams using using-authentication should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/using-authentication/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How using-authentication Compares
| Feature / Agent | using-authentication | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 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-authentication` in Fullstack Recipes
- URL: 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>
);
}
```
### 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...
}
```
### 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} />;
}
```
### 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 />;
}
```
### 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",
});
```
### Signing Up
```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("/");
},
},
});
```
### 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} />;
}
```
---
## References
- [Better Auth React](https://www.better-auth.com/docs/react)
- [Better Auth Server](https://www.better-auth.com/docs/server)Related Skills
authentication
Complete authentication system with Better Auth, email verification, password reset, protected routes, and account management.
using-workflows
Create and run durable workflows with steps, streaming, and agent execution. Covers starting, resuming, and persisting workflow results.
using-user-stories
Document and track feature implementation with user stories. Workflow for authoring stories, building features, and marking acceptance criteria as passing.
using-tests
Testing strategy and workflow. Tests run in parallel with isolated data per suite. Prioritize Playwright for UI, integration tests for APIs, unit tests for logic.
using-sentry
Capture exceptions, add context, create performance spans, and use structured logging with Sentry.
using-nuqs
Manage React state in URL query parameters with nuqs. Covers Suspense boundaries, parsers, clearing state, and deep-linkable dialogs.
using-logging
Use structured logging with Pino throughout your application. Covers log levels, context, and workflow-safe logging patterns.
using-drizzle-queries
Write type-safe database queries with Drizzle ORM. Covers select, insert, update, delete, relational queries, and adding new tables.
using-analytics
Track custom events and conversions with Vercel Web Analytics. Covers common events, form tracking, and development testing.
url-state-management
Sync React state to URL query parameters for shareable filters, search, and deep-linkable dialogs with nuqs.
testing
Complete testing setup with Neon database branching, Playwright browser tests, integration tests, and unit tests. Isolated branches with automatic TTL cleanup.
stripe-subscriptions
Complete subscription billing system with Stripe integration, feature flags for plan gating, webhook handling, and billing portal.