awesome-node-auth
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Warn
- process.env — Environment variable access in demo/advanced-telemetry-webhooks/src/index.ts
- process.env — Environment variable access in demo/angular-ssr/api-server.js
- process.env — Environment variable access in demo/angular-ssr/server.ts
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
The Sovereign Identity & Communication Layer for Node.js. Scalable by design. No SaaS/DB lock-in. MCP Server for auto-config in IDE, Hybrid Web/Mobile Auth, Dynamic in/out Webhooks via decorators, JWT/Api-Key, custom JWT Payload, RBAC/Metadata, Admin UI, served full-featured customizable Auth UI, SSE/tracking via AuthEventBus
awesome-node-auth
A production-ready, database-agnostic JWT authentication library for Node.js written in TypeScript. Drop-in auth for Express, NestJS, Next.js, Fastify and any other Node.js framework — connect to any database through a single interface.
The self-hosted alternative to Supertokens and Supabase Auth. Same enterprise-grade features, zero vendor lock-in.
Installation
npm install awesome-node-auth
Quick Start
import express from 'express';
import { AuthConfigurator, AuthEventBus } from 'awesome-node-auth';
import { myUserStore } from './my-user-store'; // your IUserStore impl
const app = express();
app.use(express.json());
const eventBus = new AuthEventBus();
const auth = new AuthConfigurator(
{
accessTokenSecret: process.env.ACCESS_TOKEN_SECRET!,
refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET!,
accessTokenExpiresIn: '15m',
refreshTokenExpiresIn: '7d',
},
myUserStore,
{ eventBus },
);
app.use(auth.buildAllRouters({
admin: {
accessPolicy: 'is-admin-flag', // admin panel for users with isAdmin: true
},
})); // mounts /auth/* and /auth/admin/*
// Grant the admin panel from a seed script or CLI task (sets isAdmin; needs IUserStore.update):
// await auth.promoteToAdmin(userId, { method: 'flag' });
app.get('/protected', auth.middleware(), (req, res) => {
res.json({ user: req.user });
});
app.listen(3000);
Implement IUserStore once for your database and you're done.
Full DB examples (MongoDB, PostgreSQL, MySQL, in-memory) → README.detailed.md.
Features
| Area | Highlights |
|---|---|
| Auth strategies | Email/password · OAuth 2.0 (Google, GitHub, custom) · Magic links · SMS OTP · TOTP 2FA |
| Token management | HttpOnly-cookie or Bearer mode · automatic access/refresh rotation · __Host-/__Secure- cookie prefixes |
| Identity Provider (IdP) mode (v1.9) | RS256-signed JWTs · public JWKS endpoint (/.well-known/jwks.json) · Resource Server middleware · zero new dependencies |
| Stateful sessions (v1.5) | ISessionStore + real-time revocation (checkOn: allcalls|refresh|none) · works behind your own L1/L2 cache layers |
| Dynamic email templates (v1.6) | ITemplateStore — per-language mail templates + UI i18n with safe hardcoded fallback · built-in MemoryTemplateStore |
| CSRF protection | Double-submit cookie pattern · __Host- prefix hardening against cookie-tossing |
| Account management | Registration · change email/password · account deletion · email verification (none/lazy/strict) |
| Account linking | Link multiple OAuth providers · conflict resolution via IPendingLinkStore |
| RBAC | IRolesPermissionsStore with tenant awareness |
| Multi-tenancy | ITenantStore for isolated tenant apps |
| Admin panel | Full-featured admin UI: user management, sessions, roles, tenants, metadata, API keys, webhooks |
| Built-in UI | Zero-dependency HTML/CSS/JS login UI served at <apiPrefix>/ui/ · headless mode for SPAs |
| Client libraries | Angular · Flutter · React · served auth.js — see Ecosystem |
| Event-driven | AuthEventBus · SSE push · inbound/outbound webhooks · telemetry |
| API keys | M2M bcrypt-hashed keys with scopes, expiry, IP allowlist and audit log |
| OpenAPI / Swagger | Auto-generated specs for auth, admin and tools routers |
Identity Provider (IdP) Mode (v1.9)
Turn any Provisioner into a central IdP that issues RS256-signed JWTs. Downstream Resource Servers validate tokens via the public JWKS endpoint — no shared secrets.
Generate the RSA private key for your .env (uses Node.js built-in crypto — no install needed):
node -e "
const { generateKeyPairSync } = require('crypto');
const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const pem = privateKey.export({ type: 'pkcs8', format: 'pem' });
console.log('IDP_PRIVATE_KEY=' + Buffer.from(pem).toString('base64'));
"
Then in your config:
// Provisioner (IdP)
const auth = new AuthConfigurator({
accessTokenSecret: '...',
refreshTokenSecret: '...',
idProvider: {
enabled: true,
issuer: 'https://auth.myplatform.com',
privateKey: Buffer.from(process.env.IDP_PRIVATE_KEY!, 'base64').toString('utf8'),
},
}, userStore);
// Resource Server (downstream)
import { createJwksAuthMiddleware } from 'awesome-node-auth';
app.use('/api', createJwksAuthMiddleware({
jwksUrl: 'https://auth.myplatform.com/.well-known/jwks.json',
issuer: 'https://auth.myplatform.com',
}), myApiRouter);
In development, if you omit
privateKeyan ephemeral keypair is auto-generated at startup.
→ Full guide: awesomenodeauth.com/docs/advanced/idp-mode
Key Endpoints
POST /auth/login POST /auth/refresh GET /auth/me
POST /auth/register POST /auth/logout GET /auth/sessions ← device list
POST /auth/forgot-password POST /auth/change-password DELETE /auth/sessions/:h ← revoke device
POST /auth/magic-link/send POST /auth/2fa/verify DELETE /auth/account
GET /auth/oauth/:provider GET /auth/oauth/:provider/callback
POST /auth/sessions/cleanup POST /auth/add-phone PATCH /auth/profile
GET /.well-known/jwks.json ← IdP mode only
Optional Stores Snapshot
const auth = new AuthConfigurator(
{ ...config, templateStore }, // ITemplateStore — dynamic email templates + UI i18n (v1.6), part of AuthConfig
userStore,
{ eventBus }, // optional; the third argument only accepts { eventBus }
);
app.use('/auth', auth.router({
sessionStore, // ISessionStore — stateful sessions + device management
metadataStore, // IUserMetadataStore — arbitrary per-user key/value pairs
rbacStore, // IRolesPermissionsStore
tenantStore, // ITenantStore
linkedAccountsStore, // ILinkedAccountsStore — several OAuth providers per user
pendingLinkStore, // IPendingLinkStore — OAuth account-linking conflicts (with linkedAccountsStore)
}));
app.get('/protected', auth.middleware(), handler); // uses the sessionStore passed to router() above (call router() first)
With buildAllRouters(), pass the same stores as auth: { … }; the admin panel takes its own in admin: { … } (see Admin UI).
Full configuration reference → README.detailed.md § Configuration
Admin UI
Use auth.buildAllRouters({ admin: ... }) to mount both the main auth router and the admin router together. The admin router lives at /auth/admin/*, and jwtSecret is auto-filled from AuthConfig.accessTokenSecret. Set accessPolicy (or a non-empty legacy adminSecret): without either, the admin routes are mounted unprotected and a WARNING is written to stderr.
admin option (AdminOptions) |
Unlocks |
|---|---|
sessionStore |
Sessions tab |
rbacStore |
Roles & Permissions tab |
tenantStore |
Tenants tab |
userMetadataStore |
Metadata section in user detail |
settingsStore |
⚙️ Control tab |
linkedAccountsStore |
Linked Accounts column |
apiKeyStore |
🔑 API Keys tab |
webhookStore |
🔗 Webhooks tab |
templateStore |
Email & UI tab |
uploadDir (optionally uploadBaseUrl) |
Logo upload in branding |
Two login endpoints, two audiences
/auth/ui/login— end-user login for your application (built-in UI,ui: { enabled: true })/auth/admin/— admin panel for operators (its sign-in form posts to/auth/admin/login)
They are intentionally different flows. If you mount the admin UI for operators, keep linking end users to /auth/ui/login.
Ecosystem
awesome-node-auth is the reference server of a family of libraries that port its HTTP API to other runtimes, plus client libraries for that API.
Servers
| Runtime | Repository | Status |
|---|---|---|
| Node.js | awesome-node-auth (this repo) |
npm awesome-node-auth |
| Go | awesome-go-auth |
Go module, 0.11.x · 1.0 in progress |
| AWS Lambda | awesome-lambda-auth |
Preview |
| Python | awesome-python-auth |
PyPI awesome-python-auth 1.1.0 |
| Rust | awesome-rust-auth |
Git only (not on crates.io) |
| Dart | awesome-dart-auth |
Git only (not on pub.dev) |
Clients
| Client | Package | Status |
|---|---|---|
| Angular | ng-awesome-node-auth |
npm · to be renamed @awesome-lang-auth/angular |
| Flutter | awesome_node_auth_flutter |
pub.dev · to be renamed awesome_flutter_auth |
| React | @awesome-lang-auth/react |
npm 0.1.0 |
| Browser | auth.js |
Served by this library at <apiPrefix>/ui/auth.js when ui.enabled is set — see Including auth.js |
Documentation
| Resource | Link |
|---|---|
| Full reference | README.detailed.md |
| Wiki / Guides | awesomenodeauth.com |
| Changelog | CHANGELOG.md |
| Demo apps | demo/ |
| Framework examples | examples/ |
The companion MCP server (
awesome-node-auth-mcp-server) has been retired and is no longer available.
License
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found
