Authentication library for Next.js applications with support for OAuth, email, and credentials authentication
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Server-side utilities for retrieving and managing user sessions in API routes, server components, middleware, and getServerSideProps functions. Essential for protecting server-side resources and implementing authentication checks.
Retrieves the current user session on the server side with support for both Pages Router and App Router patterns.
/**
* Retrieves the current user session on the server side
* @param args - Request/response objects and options (varies by router type)
* @returns Promise resolving to session object or null if not authenticated
*/
function getServerSession<O extends GetServerSessionOptions, R = any>(
...args: GetServerSessionParams<O>
): Promise<R | null>;
type GetServerSessionParams<O extends GetServerSessionOptions> =
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"], O]
| [NextApiRequest, NextApiResponse, O]
| [O]
| [];
type GetServerSessionOptions = Partial<Omit<AuthOptions, "callbacks">> & {
callbacks?: Omit<AuthOptions["callbacks"], "session"> & {
session?: (...args: any[]) => any;
};
};Usage Examples:
// App Router (server component or route handler)
import { getServerSession } from "next-auth/next";
export default async function Page() {
const session = await getServerSession();
if (!session) {
return <p>You must be signed in to view this page</p>;
}
return <p>Welcome {session.user?.name}</p>;
}
// API Route (pages/api)
import { getServerSession } from "next-auth/next";
import { authOptions } from "./auth/[...nextauth]";
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
res.status(401).json({ message: "You must be logged in." });
return;
}
res.json({ message: `Hello ${session.user?.name}` });
}
// getServerSideProps
import { getServerSession } from "next-auth/next";
import { authOptions } from "../api/auth/[...nextauth]";
export async function getServerSideProps(context) {
const session = await getServerSession(context.req, context.res, authOptions);
if (!session) {
return {
redirect: {
destination: '/api/auth/signin',
permanent: false,
},
};
}
return {
props: { session },
};
}The session object structure returned by getServerSession and available on the client side.
/**
* User session object containing authentication state and user information
*/
interface Session extends DefaultSession {
/** User information */
user?: {
name?: string | null;
email?: string | null;
image?: string | null;
/** Additional properties can be added via callbacks */
[key: string]: any;
};
/** Session expiration timestamp */
expires: ISODateString;
/** Additional session properties can be added via callbacks */
[key: string]: any;
}
interface DefaultSession {
user?: {
name?: string | null;
email?: string | null;
image?: string | null;
};
expires: ISODateString;
}Configuration options that affect server-side session behavior.
/**
* Session strategy configuration affecting server-side behavior
*/
interface SessionOptions {
/**
* Session storage strategy
* - "jwt": Stateless sessions stored in encrypted JWT cookies
* - "database": Server-side sessions stored in database via adapter
*/
strategy: "jwt" | "database";
/** Maximum session age in seconds (default: 2592000 - 30 days) */
maxAge: number;
/**
* How frequently to update session expiry in seconds
* Only applies to database sessions (default: 86400 - 24 hours)
*/
updateAge: number;
/** Custom session token generator function for database sessions */
generateSessionToken?: () => Awaitable<string>;
}Callbacks that specifically affect server-side session behavior and data transformation.
/**
* Session callback for customizing server-side session object
*/
interface SessionCallback {
session: (params: {
/** Base session object */
session: Session;
/** JWT token (when using JWT strategy) */
token: JWT;
/** User object (when using database strategy) */
user: AdapterUser;
/** New session data from session.update() */
newSession?: any;
/** Trigger that caused session callback ("update" or undefined) */
trigger?: "update";
}) => Awaitable<Session | DefaultSession>;
}Usage Example:
// Customize session object with additional user data
export const authOptions: AuthOptions = {
providers: [...],
callbacks: {
async session({ session, token, user }) {
// Add user ID to session (JWT strategy)
if (token) {
session.user.id = token.sub;
session.user.role = token.role;
}
// Add user data to session (database strategy)
if (user) {
session.user.id = user.id;
session.user.role = user.role;
}
return session;
},
},
};Advanced patterns for validating and protecting server-side resources.
/**
* Server-side session validation utilities
*/
interface ServerSessionValidation {
/** Validate session exists and optionally check conditions */
validateSession: (
session: Session | null,
requirements?: {
requireAuth?: boolean;
requireRole?: string;
requirePermission?: string;
}
) => boolean;
}Usage Examples:
// Protect API route with role-based access
import { getServerSession } from "next-auth/next";
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
return res.status(401).json({ error: "Not authenticated" });
}
if (session.user.role !== "admin") {
return res.status(403).json({ error: "Insufficient permissions" });
}
// Handle admin-only logic
res.json({ data: "Admin data" });
}
// Server component with authentication check
export default async function AdminPage() {
const session = await getServerSession();
if (!session) {
redirect('/api/auth/signin');
}
if (!session.user.isAdmin) {
redirect('/unauthorized');
}
return <AdminDashboard />;
}
// Conditional rendering based on session
export default async function ConditionalContent() {
const session = await getServerSession();
return (
<div>
{session ? (
<UserContent user={session.user} />
) : (
<PublicContent />
)}
</div>
);
}When using database session strategy, sessions are managed through the adapter interface.
/**
* Database session management interfaces
*/
interface AdapterSession {
/** Randomly generated session token */
sessionToken: string;
/** User ID associated with this session */
userId: string;
/** Session expiration date */
expires: Date;
}
interface SessionAdapterMethods {
/** Create a new session for the user */
createSession?: (session: {
sessionToken: string;
userId: string;
expires: Date;
}) => Awaitable<AdapterSession>;
/** Get session and associated user by session token */
getSessionAndUser?: (
sessionToken: string
) => Awaitable<{ session: AdapterSession; user: AdapterUser } | null>;
/** Update session expiration or other properties */
updateSession?: (
session: Partial<AdapterSession> & Pick<AdapterSession, "sessionToken">
) => Awaitable<AdapterSession | null | undefined>;
/** Delete session from database */
deleteSession?: (
sessionToken: string
) => Promise<void> | Awaitable<AdapterSession | null | undefined>;
}When using JWT session strategy, sessions are managed through encrypted JWT tokens.
/**
* JWT session token structure
*/
interface JWT extends Record<string, unknown>, DefaultJWT {
/** User identifier (subject) */
sub?: string;
/** User name */
name?: string | null;
/** User email */
email?: string | null;
/** User profile picture */
picture?: string | null;
/** Token issued at timestamp */
iat?: number;
/** Token expiration timestamp */
exp?: number;
/** JWT ID */
jti?: string;
}
interface DefaultJWT extends Record<string, unknown> {
name?: string | null;
email?: string | null;
picture?: string | null;
sub?: string;
}Method for updating session data on the server side (requires database strategy).
/**
* Update session data (database strategy only)
* Use session.update() on client side to trigger server-side session callback
*/
interface SessionUpdate {
/** Update session with new data */
update: (data?: any) => Promise<Session | null>;
}Usage Example:
// API route to update session data
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
return res.status(401).json({ error: "Not authenticated" });
}
// Update user data in database
await updateUserProfile(session.user.id, req.body);
// Session will be refreshed automatically on next request
res.json({ success: true });
}
// Session callback to include updated data
export const authOptions: AuthOptions = {
callbacks: {
async session({ session, token, user, trigger, newSession }) {
if (trigger === "update") {
// Handle session update trigger
return { ...session, ...newSession };
}
return session;
},
},
};interface GetServerSidePropsContext {
req: IncomingMessage & {
cookies: Partial<{ [key: string]: string }>;
};
res: ServerResponse;
query: ParsedUrlQuery;
resolvedUrl: string;
params?: ParsedUrlQuery;
preview?: boolean;
previewData?: any;
locale?: string;
locales?: string[];
defaultLocale?: string;
}
interface NextApiRequest extends IncomingMessage {
query: Partial<{ [key: string]: string | string[] }>;
cookies: Partial<{ [key: string]: string }>;
body: any;
}
interface NextApiResponse<T = any> extends ServerResponse {
send: (body: T) => void;
json: (body: T) => void;
status: (statusCode: number) => NextApiResponse<T>;
redirect: (statusCode: number, url: string) => NextApiResponse<T>;
}