RegisterLogin
DocsPricing
RegisterLogin
  • Getting Started
  • Introduction
  • Quick Start
  • SDKs
  • React
  • TypeScript
  • Next.js
  • Express
  • NestJS
  • Python
  • API Reference
  • Support and Resources
  • FAQ
  • Contact Support

AuthSafe

Product

HighlightFeatureIntegrationPricingFAQ

Company

AboutBlogContactSitemap

Developer

DashboardDocumentation

Legal

Terms & ConditionsPrivacyComplianceShippingCancellation

© 2026 AuthSafe. All rights reserved.

We value your privacy

This website uses cookies for anonymous analytics to help us improve your experience. No personal information is stored or shared. You can allow or reject analytics tracking at any time. See our Privacy Policy.

We use cookies for anonymous analytics. No personal info is stored. See our Privacy Policy.

API Handlers

Pre-built handlers for OAuth authentication endpoints in Next.js API routes.

Overview

AuthSafe provides ready-to-use handlers for all authentication flows:
  1. handleSignIn - Initiate OAuth sign in
  2. handleCallback - Process OAuth callback
  3. handleLogout - Sign out and clear session
  4. handleRefresh - Refresh tokens
Works with App Router & Pages Router
All handlers are compatible with both Next.js paradigms.

Import

import {
  handleSignIn,
  handleCallback,
  handleLogout,
  handleRefresh,
} from 'authsafe-nextjs/server';

handleSignIn

Redirect to AuthSafe for authentication.
async function handleSignIn(request: Request): Promise<Response>;

App Router

// app/api/auth/signin/route.ts
import { handleSignIn } from 'authsafe-nextjs/server';

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

Pages Router

// pages/api/auth/signin.ts
import { handleSignIn } from 'authsafe-nextjs/server';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const request = new Request(`http://localhost${req.url}`, {
    method: req.method,
    headers: req.headers as any,
  });

  const response = await handleSignIn(request);

  res.writeHead(response.status, {
    Location: response.headers.get('Location')!,
  });
  res.end();
}

Query Parameters

  • returnTo - Redirect URL after successful sign in
Example:
/api/auth/signin?returnTo=/dashboard

handleCallback

Process OAuth callback and set session cookies.
async function handleCallback(request: Request): Promise<Response>;

App Router

// app/api/auth/callback/route.ts
import { handleCallback } from 'authsafe-nextjs/server';

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

Pages Router

// pages/api/auth/callback.ts
import { handleCallback } from 'authsafe-nextjs/server';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const request = new Request(`http://localhost${req.url}`, {
    method: req.method,
    headers: req.headers as any,
  });

  const response = await handleCallback(request);

  // Copy cookies and redirect
  response.headers.forEach((value, key) => {
    res.setHeader(key, value);
  });

  res.writeHead(response.status);
  res.end();
}

OAuth Flow

  1. User clicks sign in button
  2. Redirected to /api/auth/signin
  3. Redirected to AuthSafe
  4. After authentication, redirected to /api/auth/callback?code=...
  5. handleCallback exchanges code for tokens
  6. Tokens stored in secure cookies
  7. User redirected to original destination

handleLogout

Sign out user and clear session cookies.
async function handleLogout(request: Request): Promise<Response>;

App Router

// app/api/auth/logout/route.ts
import { handleLogout } from 'authsafe-nextjs/server';

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

Pages Router

// pages/api/auth/logout.ts
import { handleLogout } from 'authsafe-nextjs/server';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const request = new Request(`http://localhost${req.url}`, {
    method: req.method,
    headers: req.headers as any,
  });

  const response = await handleLogout(request);

  response.headers.forEach((value, key) => {
    res.setHeader(key, value);
  });

  res.writeHead(response.status);
  res.end();
}

Query Parameters

  • returnTo - Redirect URL after logout
Example:
await fetch('/api/auth/logout?returnTo=/', { method: 'POST' });

handleRefresh

Refresh expired tokens using refresh token.
async function handleRefresh(request: Request): Promise<Response>;

App Router

// app/api/auth/refresh/route.ts
import { handleRefresh } from 'authsafe-nextjs/server';

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

Pages Router

// pages/api/auth/refresh.ts
import { handleRefresh } from 'authsafe-nextjs/server';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const request = new Request(`http://localhost${req.url}`, {
    method: req.method,
    headers: req.headers as any,
  });

  const response = await handleRefresh(request);

  const data = await response.json();
  res.status(response.status).json(data);
}

Usage

The refresh handler is typically called automatically by the SDK when tokens are about to expire:
// Client-side (automatic)
const { refreshSession } = useAuth();
await refreshSession();

Complete Setup

App Router

// app/api/auth/signin/route.ts
import { handleSignIn } from 'authsafe-nextjs/server';

export async function GET(request: Request) {
  return handleSignIn(request);
}
// app/api/auth/callback/route.ts
import { handleCallback } from 'authsafe-nextjs/server';

export async function GET(request: Request) {
  return handleCallback(request);
}
// app/api/auth/logout/route.ts
import { handleLogout } from 'authsafe-nextjs/server';

export async function POST(request: Request) {
  return handleLogout(request);
}
// app/api/auth/refresh/route.ts
import { handleRefresh } from 'authsafe-nextjs/server';

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

Error Handling

All handlers return appropriate error responses:

Sign In Errors

{
  "error": "Missing client configuration"
}

Callback Errors

{
  "error": "Invalid authorization code"
}

Logout Errors

{
  "error": "No active session"
}

Refresh Errors

{
  "error": "No refresh token available"
}

Custom Error Handling

App Router

// app/api/auth/callback/route.ts
import { handleCallback } from 'authsafe-nextjs/server';

export async function GET(request: Request) {
  try {
    return await handleCallback(request);
  } catch (error) {
    console.error('Auth callback error:', error);

    return new Response(JSON.stringify({ error: 'Authentication failed' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
}

Pages Router

// pages/api/auth/callback.ts
import { handleCallback } from 'authsafe-nextjs/server';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  try {
    const request = new Request(`http://localhost${req.url}`, {
      method: req.method,
      headers: req.headers as any,
    });

    const response = await handleCallback(request);

    res.writeHead(response.status, {
      Location: response.headers.get('Location')!,
    });
    res.end();
  } catch (error) {
    console.error('Auth error:', error);
    res.status(500).json({ error: 'Authentication failed' });
  }
}

Advanced Examples

Custom Redirect Logic

// app/api/auth/callback/route.ts
import { handleCallback } from 'authsafe-nextjs/server';
import { NextRequest } from 'next/server';

export async function GET(request: NextRequest) {
  const response = await handleCallback(request);

  // Override redirect based on user role
  const url = new URL(response.headers.get('Location')!);
  const session = await getAuth();

  if (session && hasScope('admin')) {
    url.pathname = '/admin/dashboard';
  } else {
    url.pathname = '/dashboard';
  }

  return Response.redirect(url);
}

Logging

// app/api/auth/signin/route.ts
import { handleSignIn } from 'authsafe-nextjs/server';

export async function GET(request: Request) {
  const url = new URL(request.url);
  const returnTo = url.searchParams.get('returnTo');

  console.log(`[Auth] Sign in initiated, returnTo: ${returnTo}`);

  return handleSignIn(request);
}

Security Considerations

  1. Use HTTPS in production - Always use secure cookies
  2. Validate returnTo parameter - Prevent open redirect vulnerabilities
  3. CSRF protection - Use POST for logout/refresh
  4. Rate limiting - Consider rate limiting sensitive endpoints
  5. Secure cookie settings - HttpOnly, SameSite, Secure flags

Related

  • Server Authentication - Use sessions in Server Components
  • Middleware - Route protection
  • useAuth() - Client-side authentication
  • AuthProvider - Context provider setup