Authentication Usage

Configure the authentication runtime, route handlers, providers, and client session state.

The generated auth server exposes a small set of functions from server/auth:

import {
  auth,
  currentUser,
  handlers,
  signIn,
  signOut,
  verifyAccessToken,
} from '@/server/auth'

The handlers function is the HTTP entry point. The other functions are server helpers that can be used directly inside server-side application code.

Route handling

The auth handler expects requests under /api/auth/*.

GET routes

RouteBehavior
/api/auth/sessionReturns the authenticated session or 401.
/api/auth/current-userReturns the current user or 401.
/api/auth/:providerStarts an OAuth flow.
/api/auth/:provider/callbackCompletes an OAuth flow.

POST routes

RouteBehavior
/api/auth/sign-inVerifies email/password credentials and creates a session.
/api/auth/sign-outDeletes the current refresh-token session.
/api/auth/refresh-tokenCreates a new access token for the current session.

The handler also responds to OPTIONS with 204 and returns 405 for unsupported methods.

Router integration

The handler accepts a standard Request and returns a standard Response, so it can be mounted from frameworks that expose Web Fetch-compatible handlers.

import { handlers } from '@/server/auth'

export async function GET(request: Request) {
  return handlers(request)
}

export async function POST(request: Request) {
  return handlers(request)
}

Use framework-specific request adapters when the framework does not expose a native Request.

Authentication helpers

auth

auth({ headers }) resolves the refresh token from the configured cookie or a Bearer authorization header. It validates the hashed refresh secret and refreshes the session expiry when it is inside expiresThreshold.

const session = await auth({
  headers: request.headers,
})

The returned value has token, user, and expiresAt.

currentUser

currentUser({ headers }) reads the access token, verifies the JWT, and loads the user through the adapter.

const user = await currentUser({
  headers: request.headers,
})

verifyAccessToken

const payload = await verifyAccessToken(accessToken)

if (!payload) {
  // invalid or expired token
}

The result is { userId } or null.

Credentials sign-in

The password flow looks up a credentials account by email and verifies its stored password hash.

const session = await signIn({
  email,
  password,
})

The returned object contains an access token, refresh token, and session expiry.

OAuth flow

A provider request starts at:

GET /api/auth/google

The server:

  1. Generates a random state and PKCE verifier.
  2. Stores them in short-lived cookies.
  3. Redirects to the provider.
  4. Verifies the returned state.
  5. Exchanges the code for provider data.
  6. Looks up the provider account or email.
  7. Creates the user/account when necessary.
  8. Creates a local session and redirects back.

The providers that support PKCE use S256 code challenges. Facebook uses the non-PKCE flow implemented by its provider.

Session configuration

The default configuration in the registry is:

session: {
  expiresIn: 60 * 60 * 24 * 7,
  expiresThreshold: 60 * 60 * 24,
  accessTokenExpiresIn: 60 * 15,
}

These values are examples, not mandatory production defaults. Set a strong AUTH_SECRET and choose lifetimes appropriate for your application.

Client session

SessionProvider uses React Query to fetch /api/auth/current-user.

import { SessionProvider, useSession } from '@/hooks/use-session'

function Providers({ children }: { children: React.ReactNode }) {
  return <SessionProvider>{children}</SessionProvider>
}

function AccountButton() {
  const session = useSession()

  if (session.status === 'loading') return <span>Loading...</span>
  if (session.status === 'unauthenticated') return <button>Sign in</button>

  return <span>{session.session.user.email}</span>
}

The provider also exposes signIn, signOut, and refreshToken. Successful mutations invalidate or update the current-user query.

API Reference

createAuth(config)

Returns:

{
  auth,
  currentUser,
  verifyAccessToken,
  signIn,
  signOut,
  handlers,
}

AuthConfig

interface AuthConfig {
  secret: string
  adapter: AuthAdapter
  providers: BaseProvider[]
  session: {
    expiresIn: number
    expiresThreshold: number
    accessTokenExpiresIn: number
  }
  cookies: {
    keys: {
      accessToken: string
      refreshToken: string
      state: string
      codeVerifier: string
      redirectUri: string
    }
    options: {
      Path: string
      HttpOnly: boolean
      Secure: boolean
      SameSite: 'Lax' | 'Strict' | 'None'
      Domain?: string
      Expires?: Date | string
      'Max-Age'?: number
    }
  }
}

SessionProvider

{
  children: React.ReactNode
}

useSession

Returns the current session state together with:

signIn(opts: { email: string; password: string })
signOut()
refreshToken()

On this page