@authbase/node
authbase for Node backends (Node 20.19+, ESM): a typed client for the end-user API and offline access-token verification, with helpers for Express, Hono and Next.js. Not on npm yet (it will be at the public release): install it from a packed tarball.
cd sdk/typescript && npm ci && npm run build && npm pack # → authbase-node-0.1.0.tgzcd your-app && npm install ../authbase/sdk/typescript/authbase-node-0.1.0.tgzThe client
Section titled “The client”One per app, with the app’s API key from the environment (never in code):
import { Authbase, AuthbaseError } from "@authbase/node";
const authbase = new Authbase({ url: process.env.AUTHBASE_URL!, apiKey: process.env.AUTHBASE_API_KEY! });
await authbase.users.create({ email, password });const tokens = await authbase.auth.login({ identifier: email, password, client_ip: req.ip });const next = await authbase.auth.refresh({ refresh_token: tokens.refresh_token });await authbase.auth.logout({ refresh_token: next.refresh_token });Every method throws AuthbaseError on a non-2xx answer: status, code
(branch on this), detail, requestId, errors (per field, for 422) and
retryAfter (429/503). An unreachable server is code: "network_error".
Verifying access tokens
Section titled “Verifying access tokens”Tokens are verified locally against the app’s JWKS: fetched once, cached
for 5 minutes, refetched (at most once a second) when a token carries an
unknown kid, so a signing-key rotation needs no restart. Only EdDSA,
typ: at+jwt, the app’s issuer and the app id as aud are accepted.
const claims = await authbase.verifyAccessToken(token); // learns issuer and app id once from GET /v1/appA service that only checks tokens needs no API key:
import { createVerifier } from "@authbase/node";const verify = createVerifier({ issuer: "https://auth.example.com/apps/cashmate", appId: "01a0…" });A bad token throws AuthbaseTokenError (token_expired, worth a refresh,
or token_invalid). A JWKS that cannot be fetched throws something else:
that is an outage, not the caller’s fault.
Framework helpers
Section titled “Framework helpers”Each takes the client or { issuer, appId }, and optionally { roles }
(all required). Missing or bad tokens get 401 with WWW-Authenticate: Bearer (RFC 6750), missing roles 403, an unreachable JWKS 503; bodies are
problem+json.
// Expressimport { requireAuth } from "@authbase/node/express";app.get("/me", requireAuth(authbase), (req, res) => res.json({ id: req.auth!.sub }));
// Honoimport { requireAuth, type AuthVariables } from "@authbase/node/hono";const app = new Hono<{ Variables: AuthVariables }>();app.get("/me", requireAuth(authbase, { roles: ["admin"] }), (c) => c.json({ id: c.get("auth").sub }));
// Next.js route handler (app/api/me/route.ts)import { withAuth } from "@authbase/node/next";export const GET = withAuth(authbase, async (req, { auth }) => Response.json({ id: auth.sub }));Development
Section titled “Development”npm run check regenerates the client from api/openapi/openapi.yaml
(and fails if the committed copy is stale), typechecks, tests and builds.
AUTHBASE_TEST_URL=http://localhost:8080 npm test also runs the
integration test against a real instance.
For agents: this page as markdown · llms.txt