Node.js SDK
@authon/node — Server-side SDK for verifying JWTs, managing users, and integrating Authon into any Node.js backend framework.
Installation
npm install @authon/nodeInitialization
Create a single AuthonBackend instance and reuse it throughout your application. Use your secret key — never expose it to the client.
import { AuthonBackend } from "@authon/node";
export const authon = new AuthonBackend(
process.env.AUTHON_SECRET_KEY!, // sk_live_... or sk_test_...
{
// Optional — override the API base URL
apiUrl: "https://api.authon.dev",
}
);sk_live_on the client side. It grants full admin access to your project.Token Verification
Verify a JWT access token sent from the client in the Authorization header. Returns the full user object if the token is valid.
import { authon } from "@/lib/authon";
// Verify token and get the AuthonUser
async function getAuthenticatedUser(request: Request) {
const authHeader = request.headers.get("Authorization");
if (!authHeader?.startsWith("Bearer ")) return null;
const token = authHeader.slice(7);
try {
const user = await authon.verifyToken(token);
return user;
} catch {
return null;
}
}
// user is an AuthonUser:
// {
// id, projectId, email, displayName, avatarUrl, phone,
// emailVerified, phoneVerified, isBanned,
// publicMetadata, lastSignInAt, signInCount,
// createdAt, updatedAt
// }User Management
Theauthon.users namespace provides full CRUD operations for users in your project.
users.list()
Paginate through users with optional search filtering.
const result = await authon.users.list({
page: 1, // 1-indexed page number
limit: 20, // results per page (max 100)
search: "john", // search by email or display name
});
// result: { data: AuthonUser[], total: number, page: number, limit: number }
console.log(`${result.total} users, showing page ${result.page}`);users.get()
const user = await authon.users.get("usr_abc123");
console.log(user.email, user.displayName);users.create()
Create a user directly without going through the sign-up flow. Useful for importing users or creating admin accounts.
const user = await authon.users.create({
email: "newuser@example.com",
password: "securepassword", // optional — omit for OAuth-only users
displayName: "New User",
});users.update()
Update user profile data or attach arbitrary metadata via publicMetadata.
const updated = await authon.users.update("usr_abc123", {
displayName: "Updated Name",
publicMetadata: {
plan: "pro",
onboarded: true,
orgId: "org_xyz",
},
});users.delete()
// Permanently delete a user and all associated sessions
await authon.users.delete("usr_abc123");users.ban() / users.unban()
Banning a user revokes all active sessions and prevents future logins. The user record is preserved — use delete() to remove permanently.
// Ban a user (revokes all sessions)
const banned = await authon.users.ban("usr_abc123", "Violated ToS section 4.2");
console.log(banned.isBanned); // true
// Restore a banned user
const unbanned = await authon.users.unban("usr_abc123");
console.log(unbanned.isBanned); // falseExpress Middleware
TheexpressMiddleware method returns an Express middleware that verifies the token and attaches the user to req.authonUser.
import express from "express";
import { authon } from "@/lib/authon";
const app = express();
// Optional — apply globally
app.use(async (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader?.startsWith("Bearer ")) {
try {
req.authonUser = await authon.verifyToken(authHeader.slice(7));
} catch {
// Invalid token — req.authonUser remains undefined
}
}
next();
});
// Protected route
app.get("/api/me", (req, res) => {
if (!req.authonUser) {
return res.status(401).json({ error: "Unauthorized" });
}
res.json({ user: req.authonUser });
});
// TypeScript augmentation
declare global {
namespace Express {
interface Request {
authonUser?: import("@authon/shared").AuthonUser;
}
}
}Webhook Verification
Useauthon.webhooks.verify() to validate incoming webhook payloads. It uses timing-safe comparison to prevent timing attacks.
import express from "express";
import { authon } from "@/lib/authon";
const router = express.Router();
// IMPORTANT: use raw body parser for webhook routes
router.post(
"/webhooks/authon",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.headers["authon-signature"] as string;
let event: Record<string, unknown>;
try {
event = authon.webhooks.verify(
req.body, // Buffer — raw request body
signature, // "sha256=abc123..."
process.env.AUTHON_WEBHOOK_SECRET!,
);
} catch {
return res.status(401).json({ error: "Invalid signature" });
}
// Process the verified event
switch (event.type) {
case "user.created": {
const user = (event.data as any).user;
console.log("New user signed up:", user.email);
// e.g. add to CRM, send welcome email
break;
}
case "user.banned": {
const user = (event.data as any).user;
console.log("User banned:", user.id);
break;
}
case "session.revoked": {
console.log("Session revoked:", event.id);
break;
}
}
res.json({ received: true });
}
);
export default router;