Skip to content
AtheronDEVELOPERS
← JavaScript and TypeScript SDK

Next.js (JavaScript and TypeScript)

Sign in with Atheron in Next.js.

Sign in to see your own test client ID in the samples.

Coming soon. @aton-network/sdk is not published on npm yet, so the install line on this page does not work until it is. Until then, everything works over plain HTTP: pick cURL in any code block, or start from Endpoints.

@aton-network/nextjs signs people in to a Next.js app (App Router): one route file for every sign-in route, the person in server components and server actions, and protection in proxy.ts.

Install

Set these on your server (never in code): ATHERON_CLIENT_ID, ATHERON_CLIENT_SECRET (server apps), ATHERON_REDIRECT_URI (the callback address you registered, such as https://your.app/auth/callback) and ATHERON_SECRET (32 or more random characters for sealing cookies: openssl rand -base64 32).

bash
npm install @aton-network/nextjs

Add the routes

This answers /auth/sign-in, /auth/callback, /auth/sign-out and /auth/session. Link to /auth/sign-in?return_to=/account to sign somebody in and bring them back.

This example is not written in cURL yet. Showing Next.js.

// app/auth/[...atheron]/route.ts: every Sign in with Atheron route in one file.
// Set ATHERON_CLIENT_ID, ATHERON_CLIENT_SECRET, ATHERON_SECRET and
// ATHERON_REDIRECT_URI=https://your.app/auth/callback (the address you registered).
import { Atheron } from "@aton-network/nextjs";

const atheron = Atheron();

export const { GET, POST } = atheron.handlers;

Protect pages

In a server component, read the person with await atheron.user(await cookies()); it is null for nobody.

This example is not written in cURL yet. Showing Next.js.

// proxy.ts (middleware.ts before Next 16): anybody not signed in goes to Atheron first, then back.
import { Atheron } from "@aton-network/nextjs";

const atheron = Atheron({ protect: ["/account", "/settings"] });

export async function proxy(request: Request): Promise<Response | undefined> {
  return atheron.proxy(request);
}

// In a server component, read the person with: await atheron.user(await cookies())

Webhooks

This example is not written in cURL yet. Showing TypeScript.

// Check that a webhook came from Atheron before you act on it. Pass the raw body, exactly as received.
import { verifyWebhook, type WebhookEvent } from "@aton-network/sdk";

export async function handleWebhook(request: Request): Promise<Response> {
  const raw = await request.text();
  const ok = await verifyWebhook(request.headers.get("atheron-signature"), raw, process.env.ATHERON_WEBHOOK_SECRET!);
  if (!ok) return new Response("bad signature", { status: 400 });
  const event = JSON.parse(raw) as WebhookEvent;
  if (event.type === "consent.revoked") {
    // Delete the refresh token you hold for event.data.sub, and stop using what you read.
  }
  return new Response(null, { status: 204 });
}

How it keeps you safe

  • PKCE (S256), state and nonce on every sign-in, checked in that order when the browser comes back.
  • The flow and the session live in HTTP-only cookies sealed with AES-256-GCM, so the browser carries them but cannot read or change them. Tokens never reach your page's JavaScript.
  • Sign-out is a POST from your own site only, and revokes the refresh token at Atheron.
  • A return address is always a path on your own site.

The same rules hold in every Atheron SDK: they all run one set of conformance tests.

Ask Atlas

AI assistant

Ask anything about Sign in with Atheron, the API or the portal. You get an answer from our docs, with links to the pages it used.