[data-reveal]{opacity:1!important;transform:none!important}
Auth

Authentication Basics

Authentication verifies the identity of users or systems accessing your API. The Interface Auth provides a complete system for token-based authentication with customizable sources, verifiers, and validators.

Authentication flow

A typical authentication flow consists of four steps:

  1. Token generation - Sign user data into a token using SignRaw or SignServerResponse.
  2. Token storage - Store the token on the client (cookie, header, local storage).
  3. Token validation - Verify the token when the client makes a request.
  4. Authorization - Check whether the authenticated user has permission to access the requested resource.

Example authentication flow

import { SignRaw, Authentication } from "@antelopejs/interface-auth";
import { Controller, Post, Get, JSONBody, HTTPResult } from "@antelopejs/interface-api";

class UserController extends Controller("/users") {
  @Post("login")
  async login(@JSONBody() credentials: { email: string; password: string }) {
    // Validate credentials against your data store
    const user = await validateUserCredentials(credentials);

    // Step 1: Generate a token
    const token = await SignRaw(
      { userId: user.id, role: user.role },
      { expiresIn: "1h" },
    );

    // Step 2: Return token to the client
    const result = new HTTPResult(200, {
      success: true,
      user: { id: user.id, role: user.role },
    });

    result.addHeader(
      "Set-Cookie",
      `ANTELOPEJS_AUTH=${token}; HttpOnly; Path=/`,
    );

    return result;
  }

  @Get("profile")
  async getProfile(
    @Authentication() userData: { userId: number; role: string },
  ) {
    // Steps 3 & 4: Token is automatically validated
    // If the token is invalid, an error is thrown before this code runs
    return { user: await getUserProfile(userData.userId) };
  }
}

Authentication sources

An AuthSource function extracts the authentication token from the incoming HTTP request. The default source checks two locations in order:

  1. Custom header - The x-antelopejs-auth header
  2. Cookie - The ANTELOPEJS_AUTH cookie

Create a custom source

Implement the AuthSource type to extract tokens from a different location.

import { CreateAuthDecorator, AuthSource } from "@antelopejs/interface-auth";
import type { IncomingMessage } from "node:http";

const bearerTokenSource: AuthSource = (req: IncomingMessage) => {
  const header = req.headers.authorization;
  if (header?.startsWith("Bearer ")) {
    return header.slice(7);
  }
  return undefined;
};

const BearerAuth = CreateAuthDecorator({
  source: bearerTokenSource,
});

The AuthSource type signature is:

type AuthSource = (
  req: IncomingMessage,
  res: ServerResponse,
) => string | undefined;

Authentication verifiers

An AuthVerifier function validates the token and extracts its payload. The default verifier uses ValidateRaw, which delegates to the underlying token verification implementation (typically JWT).

Create a custom verifier

import { CreateAuthDecorator, AuthVerifier } from "@antelopejs/interface-auth";

const base64Verifier: AuthVerifier<{ userId: string }> = (data?: string) => {
  if (!data) {
    throw new Error("No authentication data provided");
  }
  try {
    const decoded = Buffer.from(data, "base64").toString("utf-8");
    return JSON.parse(decoded);
  } catch {
    throw new Error("Invalid authentication data");
  }
};

const Base64Auth = CreateAuthDecorator({
  authenticator: base64Verifier,
});

The AuthVerifier type signature is:

type AuthVerifier<T = unknown> = (
  data?: string,
  options?: VerifyOptions,
) => Promise<T> | T;

Authentication validators

An AuthValidator function performs additional checks on the verified data. Validators run after the verifier and can transform the result or throw an error to reject the request.

import { CreateAuthDecorator, AuthValidator } from "@antelopejs/interface-auth";

interface UserPayload {
  userId: number;
  role: string;
}

const adminValidator: AuthValidator<UserPayload, UserPayload> = (userData) => {
  if (!userData || userData.role !== "admin") {
    throw new Error("Admin access required");
  }
  return userData;
};

const AdminOnly = CreateAuthDecorator({
  validator: adminValidator,
});

The AuthValidator type signature is:

type AuthValidator<T = unknown, R = unknown> = (
  data: T,
) => Promise<R> | R;

Authentication pipeline

The complete authentication pipeline processes the request through three stages:

source(req, res) => authenticator(token, options) => validator(data) => Parameter

Each stage is optional and falls back to the default behavior when not specified. The source extracts the token, the authenticator verifies it, and the validator performs any additional checks before the data is injected into the handler parameter.