Authentication
Prerequisites
Authentication requires the @antelopejs/interface-auth package. Install it in your module and import from @antelopejs/interface-auth.
npm install @antelopejs/interface-auth @antelopejs/interface-api
yarn add @antelopejs/interface-auth @antelopejs/interface-api
pnpm add @antelopejs/interface-auth @antelopejs/interface-api
The @antelopejs/interface-auth package provides token signing and validation. The @antelopejs/interface-api package provides controller and route decorators for protecting endpoints.
Signing Tokens
The SignRaw function creates a signed JWT token from a data payload. The token encodes the payload and can be verified later with ValidateRaw. An optional second argument controls token expiration and activation timing.
import { SignRaw } from "@antelopejs/interface-auth";
const token = await SignRaw(
{ userId: "123", role: "admin" },
{ expiresIn: "24h" }
);
The options object supports these fields:
| Option | Description |
|---|---|
expiresIn | Duration until the token expires (e.g., "1h", "7d", "30m") |
notBefore | Duration before the token becomes valid |
expiresIn on tokens used for user sessions. Tokens without expiration remain valid indefinitely if the signing key is not rotated.Validating Tokens
The ValidateRaw function verifies a token's signature and returns the decoded payload. It throws an error if the token is invalid, expired, or not yet active.
import { ValidateRaw } from "@antelopejs/interface-auth";
const payload = await ValidateRaw(token);
// payload: { userId: "123", role: "admin", iat: ..., exp: ... }
The returned payload includes the original data plus standard JWT claims (iat for issued-at, exp for expiration). An optional second argument provides validation options.
| Option | Description |
|---|---|
ignoreExpiration | Accept expired tokens |
ignoreNotBefore | Accept tokens before their notBefore time |
maxAge | Maximum allowed age of the token |
Pass these options as the second argument to ValidateRaw:
// Accept expired tokens (useful for refresh flows)
const payload = await ValidateRaw(token, { ignoreExpiration: true });
ignoreExpiration in controlled scenarios such as token refresh endpoints. Accepting expired tokens in regular authentication weakens security.Protecting Routes with @Authentication
The @Authentication parameter decorator extracts and validates a token from the incoming request automatically. It reads the token from the x-antelopejs-auth header or an ANTELOPEJS_AUTH cookie, validates it, and injects the decoded payload into the handler method.
import { Controller, Get } from "@antelopejs/interface-api";
import { Authentication } from "@antelopejs/interface-auth";
class ProfileController extends Controller("/api/profile") {
@Get("me")
async getProfile(@Authentication() auth: any) {
return { userId: auth.userId, role: auth.role };
}
}
Requests without a valid token receive an authentication error response. The decorator handles token extraction and validation entirely, so the handler method only runs for authenticated requests.
Server-Side Cookie Authentication
The SignServerResponse function creates a signed token and sets it as an HTTP cookie on the response. This approach stores the authentication token in a cookie rather than requiring the client to manage it manually.
import { Controller, Post, JSONBody, Context, type RequestContext } from "@antelopejs/interface-api";
import { SignServerResponse } from "@antelopejs/interface-auth";
class AuthController extends Controller("/api/auth") {
@Post("login")
async login(@JSONBody() body: { email: string; password: string }, @Context() ctx: RequestContext) {
const user = await validateCredentials(body.email, body.password);
await SignServerResponse(
ctx.rawResponse,
{ userId: user.id, role: user.role },
{ expiresIn: "7d" }
);
return { success: true };
}
}
The function accepts four arguments:
| Argument | Description |
|---|---|
res | The raw ServerResponse object (ctx.rawResponse from the request context) |
data | The payload to encode in the token |
signOptions | Token signing options (same as SignRaw) |
cookieOptions | Optional cookie configuration (path, domain, secure, etc.) |
Subsequent requests from the client automatically include the cookie. The @Authentication decorator reads tokens from the ANTELOPEJS_AUTH cookie in addition to the x-antelopejs-auth header.
Custom Auth Decorators
The CreateAuthDecorator function builds a specialized authentication decorator with custom extraction, verification, and validation logic. Custom decorators are useful when you need role-based access control or multi-tenant authentication.
import { CreateAuthDecorator, ValidateRaw } from "@antelopejs/interface-auth";
import type { IncomingMessage, ServerResponse } from "node:http";
const AdminAuth = CreateAuthDecorator({
source(req: IncomingMessage, _res: ServerResponse) {
const header = req.headers["authorization"];
return typeof header === "string" ? header.replace("Bearer ", "") : undefined;
},
async authenticator(token?: string) {
const payload = await ValidateRaw(token);
if ((payload as any).role !== "admin") {
throw new Error("Admin access required");
}
return payload;
},
});
export { AdminAuth };
The callbacks object accepts four optional fields: source extracts the token from the request, authenticator verifies the token, authenticatorOptions provides options for verification, and validator performs additional validation on the verified data. Use the custom decorator on any route handler just like @Authentication.
import { Controller, Get } from "@antelopejs/interface-api";
import { AdminAuth } from "../auth/admin-auth";
class AdminController extends Controller("/api/admin") {
@Get("dashboard")
async dashboard(@AdminAuth() auth: any) {
return { message: "Welcome, admin", userId: auth.userId };
}
}
Only requests with a valid admin token can access this route. The custom decorator encapsulates the role check, keeping handler methods focused on business logic.
Authentication Flow
A typical authentication flow combines token signing, cookie management, and route protection into a cohesive system.
User registers or logs in
The server validates credentials and issues a signed token. The server returns the token in the response body or sets it as a cookie.
Client sends the token with requests
The client includes the token in the x-antelopejs-auth header, or the browser sends it automatically as the ANTELOPEJS_AUTH cookie.
Route handlers validate the token
The @Authentication decorator extracts and validates the token before the handler runs. Invalid or missing tokens result in an error response.
Token expires and is refreshed
When a token expires, the client requests a new one using a refresh endpoint. The refresh endpoint validates the expired token with ignoreExpiration and issues a fresh token.
This pattern keeps authentication logic separate from business logic. Controllers declare their authentication requirements through decorators, and the auth system handles the rest.