Authentication (Sessions via Cookie)
This guide demonstrates a simple pattern for implementing authentication in React Just using session cookies. It leverages the request and response utilities to read and set cookies inside Server Components and Server Functions.
TL;DR
- Use a session cookie named
sessionthat stores an opaque, randomly generated session ID. - On login, create the session and set the cookie.
- On logout, delete the session and clear the cookie.
- To read the current user in any Server Component or Server Function, call
getUser, which parses the Cookie header to obtain the session ID, and then the user data.
What you need
requestto read the incoming Cookie header.responseto set Set-Cookie on successful login or logout.- A session store mapping session ID to an user (e.g., a database table or a fast KV store like Redis).
- A cookie utility such as
cookie,tough-cookie, or similar to parse/serialize cookies (recommended).
Security notes
Always set HttpOnly and SameSite (e.g., Lax) for session cookies; add Secure in production so cookies are sent only over HTTPS.
Never store credentials or PII in the cookie; store only an opaque session ID.
Implementation skeleton
Minimal end-to-end pattern. Replace the placeholders YourAuth, YourSessionStore, YourUserStore with your app logic.
Login and Logout
Start by implementing the login and logout methods with their respective views and components.
"use server";
import { request, response } from "react-just/server";
import { parse as parseCookie, serialize as serializeCookie } from "cookie";
export async function login(_currentState: unknown, formData: FormData) {
const email = String(formData.get("email") ?? "");
const password = String(formData.get("password") ?? "");
const userId = await YourAuth.verify(email, password);
if (!userId) return { error: "Invalid credentials" };
const sessionId = await YourSessionStore.create(userId);
const res = response();
res.headers.append(
"Set-Cookie",
serializeCookie("session", sessionId, {
path: "/",
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
}),
);
return { error: null };
}
export async function logout(): Promise<void> {
const req = request();
const cookieHeader = req.headers.get("cookie") ?? "";
const { session: sessionId } = parseCookie(cookieHeader);
if (sessionId) await YourSessionStore.destroy(sessionId);
const res = response();
res.headers.append(
"Set-Cookie",
serializeCookie("session", "", {
path: "/",
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
maxAge: 0,
}),
);
}Login Component
"use client";
import { useActionState } from "react";
import { login } from "./auth";
export default function Login() {
const [{ error }, action] = useActionState(login, { error: null });
return (
<form action={action}>
<input type="email" name="email" required placeholder="Email" />
<input type="password" name="password" required placeholder="Password" />
<button type="submit">Log in</button>
{error && <p>{error}</p>}
</form>
);
}Logout Component
import { logout } from "./auth";
export function LogoutButton() {
return (
<form action={logout}>
<button type="submit">Log out</button>
</form>
);
}getUser Utility
Create the getUser function to retrieve the user while rendering or executing a server function.
"use server";
interface User {
id: string;
email: string;
}
export async function getUser(): Promise<User | null> {
const req = request();
const cookieHeader = req.headers.get("cookie") ?? "";
const { session: sessionId } = parseCookie(cookieHeader);
if (!sessionId) return null;
const userId = await YourSessionStore.getUserId(sessionId);
if (!userId) return null;
return await YourUserStore.findById(userId);
}import Login from "./Login";
import { LogoutButton } from "./LogoutButton";
import { getUser } from "./auth";
export default async function Header() {
const user = await getUser();
return (
<header>
{user ? (
<>
<span>{user.email}</span>
<LogoutButton />
</>
) : (
<Login />
)}
</header>
);
}"use server";
import { getUser } from "./auth";
export async function updatePreferences(formData: FormData) {
const user = await getUser();
if (!user) return { error: "UNAUTHENTICATED" };
// Business logic here
return { error: null };
}See the Server Utilities reference for more details on request and response.