StarterApp Docs
Authentication

Overview

Authentication with BetterAuth and Convex

StarterApp combines BetterAuth for session management with Convex for real-time data synchronization. The authentication system provides OAuth integration, secure session handling, and client-server state management.

Production-Ready Authentication

The authentication stack includes OAuth providers, session cookies with HttpOnly security, and real-time user state synchronization between BetterAuth and Convex.

Architecture

The authentication stack bridges BetterAuth and Convex through three integration points:

BetterAuth Configuration

Located in convex/lib/auth.ts, the createAuth function configures session cookies, OAuth providers, and database integration:

export const createAuth = (ctx: ConvexGenericCtx) => {
  const baseURL = computeBaseURL(process.env);
  const socialProviders = computeSocialProviders(process.env);

  return betterAuth({
    baseURL,
    database: convexAdapter(ctx, betterAuthComponent),
    session: {
      expiresIn: 60 * 60 * 24 * 7, // 7 days
      updateAge: 60 * 60 * 24,     // 1 day
      cookie: sessionCookie,
    },
    plugins: [convex()],
    ...(socialProviders && { socialProviders }),
  });
};

Convex Integration

The convex/auth.ts module exports lifecycle hooks and the getCurrentUser query:

export const getCurrentUser = query({
  args: {},
  handler: async (ctx) => {
    const userMetadata = await betterAuthComponent.getAuthUser(ctx);
    if (!userMetadata) return null;

    const user = await ctx.db.get(userMetadata.userId);
    if (!user) return null;

    return { ...user, ...userMetadata };
  },
});

Next.js Server Helpers

The packages/app-shell/src/lib/auth/server.ts module provides server-side utilities:

export async function getCurrentSession(): Promise<UserSession | null> {
  const createAuth = await getCreateAuthFunction();
  const token = await getToken(createAuth);
  if (!token) return null;

  const user = await fetchQuery(api.auth.getCurrentUser, {}, { token });
  if (!user) return null;

  return {
    user: {
      id: user.userId,
      name: user.name,
      email: user.email,
      image: user.image,
    },
    session: {
      userDocId: user._id,
      userId: user.userId,
    },
  };
}

export async function requireUser() {
  const session = await getCurrentSession();
  if (!session) redirect("/sign-in");
  return session.user;
}

Security Features

Production-Ready Security

Authentication routes include comprehensive protections by default.

The authentication layer enforces:

  • HttpOnly session cookies with __Host- prefix in production
  • Same-origin CSRF protection using Fetch Metadata and origin validation
  • Strict cache control via force-dynamic and force-no-store exports
  • Security headers including X-Content-Type-Options and Referrer-Policy
  • Node runtime for full request/response control

Implementation Files

Prop

Type

Import Patterns

Always import createAuth from convex/lib/auth, not from convex/http.ts. The HTTP module includes side effects that break Next.js server components.

AI Context

For AI-assisted development, the codebase includes comprehensive patterns in:

These files enable AI assistants to implement authentication correctly on first attempt.