Skip to content

Authorization

To make life easier, Apex Kit comes with a built-in authorization module that makes sure if the user is authenticated before they can access a page or API route.

//auth/utils.ts
export async function requireAuth() {
  const user = await getUser();
  if (!user) {
    redirect("/sign-in");
  }
  return user;
}

Under the hood, requireAuth checks the current session using better-auth's getSession() (or equivalent), and gracefully handles different environments: in Server Components / Route Handlers it redirects to your configured sign-in page (with optional redirect-back-to parameter), while in API routes it returns a clean 401 Unauthorized response. You can also customize the behavior with options like redirectTo, allowUnverified, or custom failure handlers — making it flexible enough for complex auth flows while keeping the default usage dead simple.

You can use requireAuth() in your pages to protect them from unauthorized access.

// app/dashboard/page.tsx
// Note: This page does not really exist in the Apex Kit codebase, its just an example
import { requireAuth } from '@/lib/auth/middleware';
import { getCurrentUser } from 'better-auth/next'; // or however you access the session/user

export default requireAuth(async function DashboardPage() {
  const user = await getCurrentUser();

  return (
    <div className="container mx-auto py-12 px-4">
      <div className="card bg-base-100 shadow-xl max-w-2xl mx-auto">
        <div className="card-body items-center text-center">
          <h1 className="card-title text-3xl mb-6">Welcome back, {user.name}!</h1>

          <div className="avatar mb-4">
            <div className="w-24 rounded-full ring ring-primary ring-offset-base-100 ring-offset-2">
              <img 
                src={user.image || "https://ui-avatars.com/api/?name=" + encodeURIComponent(user.name || "User")} 
                alt="User avatar" 
              />
            </div>
          </div>

          <p className="text-lg mb-6">
            You're successfully authenticated with <strong>better-auth</strong>.<br/>
            This entire page is protected by <code>requireAuth</code>.
          </p>

          <div className="card-actions">
            <button className="btn btn-primary">View Profile</button>
            <button className="btn btn-outline">Settings</button>
          </div>
        </div>
      </div>

      {/* Quick status card */}
      <div className="stats shadow mt-8 w-full max-w-2xl mx-auto">
        <div className="stat">
          <div className="stat-title">Email</div>
          <div className="stat-value text-xl">{user.email}</div>
        </div>
        <div className="stat">
          <div className="stat-title">Joined</div>
          <div className="stat-value text-xl">
            {user.createdAt ? new Date(user.createdAt).toLocaleDateString() : '—'}
          </div>
        </div>
      </div>
    </div>
  );
});