KeyloomKeyloom
Keyloom Auth is currently in beta. Feedback and contributions are welcome!
Nextjs

Next.js Handler (API routes)

The createNextHandler API and the built-in endpoints exposed under /api/auth/[[...keyloom]].

Handler: createNextHandler

Exports GET/POST handlers for the Keyloom API routes in the App Router.

import { createNextHandler } from "@keyloom/nextjs";
import config from "@/keyloom.config";
export const { GET, POST } = createNextHandler(config);

Endpoints

The handler maps these endpoints:

GET

  • GET /api/auth/session{ session, user } (DB or JWT strategy)
  • GET /api/auth/csrf → issues CSRF token and sets __keyloom_csrf
  • GET /api/auth/oauth/:provider/start → redirects to provider
  • GET /api/auth/oauth/:provider/callback → handles provider callback, sets session cookie, redirects

POST

  • POST /api/auth/oauth/:provider/callback → form_post callback (Apple etc.)
  • POST /api/auth/register{ userId, requiresVerification }
  • POST /api/auth/login → sets session cookie, returns { sessionId }
  • POST /api/auth/logout → clears session cookie, { ok: true }
  • POST /api/auth/password/request → issues verification token (store via adapter), { ok: true }
  • POST /api/auth/password/reset → uses token, updates credential, { ok: true }
  • POST /api/auth/email/verify → uses token, sets emailVerified, { ok: true }

Configuration Notes

  • config.adapter is used for user/session/token storage
  • config.secrets.authSecret is required to seal OAuth state and hash verification tokens
  • config.baseUrl is used to build OAuth callback URLs
  • config.session.ttlMinutes influences login session TTL (database strategy)

Hooks and Plugins

  • config.hooks.onRequest({ kind, req }) → optionally return a Response to short-circuit (deny/redirect/metrics)
  • config.plugins → array of additional { method: 'GET'|'POST'; path: RegExp; handler(req, ctx) }

JWT Strategy

When config.sessionStrategy === 'jwt' (or equivalent env), the handler will:

  • For GET /session, infer jwksUrl and verify the access token from cookies or Authorization header
  • For login, you typically use @keyloom/server to issue tokens and set __keyloom_access/__keyloom_refresh

See the JWT page and jwt-server utilities for details.

Error Handling

  • 404 { error: 'not_found' } for unknown paths
  • 405 { error: 'method_not_allowed' } for unsupported methods
  • 403 { error: 'csrf' } if CSRF validation fails for state-changing POSTs
  • 400 { error: 'invalid_request'|'invalid_token' } for malformed inputs

Example: Custom provider start

// /app/sign-in/page.tsx
function SignInPage() {
  return (
    <a href="/api/auth/oauth/github/start?callbackUrl=/dashboard">
      Continue with GitHub
    </a>
  );
}

Request/response schemas (summary)

MethodPathSuccessErrors
GET/api/auth/session200 { user, session } or { user: null, session: null }401 { error: 'unauthorized' }
GET/api/auth/csrf200 { token } and Set-Cookie-
POST/api/auth/login200 { sessionId } and Set-Cookie400 { error: 'invalid_request' }
POST/api/auth/logout200 { ok: true } and clears cookies-
GET/POST/api/auth/oauth/:provider/(start|callback)302 Redirect with cookies set on success400/401 provider error details
GET/api/auth/jwks200 { keys: Jwk[] }-

See Server overview for deeper schemas.

Example: custom start and callback

app/api/auth/[...keyloom]/route.ts
import { createNextHandler } from "@keyloom/nextjs";
import cfg from "@/keyloom.config";

export const { GET, POST } = createNextHandler(cfg, {
  onRequest: ({ kind, req }) => {
    // add logging, rate limiting, or A/B testing here
  },
});

Performance and edge notes

  • Prefer App Router route handlers for streaming and simpler responses
  • Keep handlers stateless; use adapter for persistence
  • JWT strategy minimizes DB lookups on /session
  • Cache JWKS at the server boundary

Troubleshooting

  • CSRF error on POST: ensure CSRF cookie present, same-site rules, and token header/body included
  • 405 errors: check you export both GET and POST and match your route file path
  • Provider callback failure: confirm provider app settings and exact callback URL

See also

Next steps

  • Add a sign-in page with provider start links
  • Wire logout and session display in your layout

How is this guide?