authkit-js
v0.2.5
Published
Express auth toolkit (JWT, Sessions with Redis, Google/GitHub OAuth) in JavaScript
Downloads
25
Maintainers
Readme
AuthKit-JS (Express) — JWT, Sessions (Redis), Google/GitHub OAuth
A simple, pluggable authentication library for Express.js applications. Designed to support multiple strategies:
- 🔑 JWT Authentication
- 🗝 Session Authentication (Memory / Redis store)
- 🌐 Google OAuth2
- 🐙 GitHub OAuth2
- 📘 Facebook OAuth2
- Apple Sign In (OAuth/OIDC)
- 🔒 Middleware helpers (
makeAuthenticate,requireAuth) - 🔢 Built-in TOTP 2FA utilities (secret + QR generation, token verify)
✨ Features
- Drop-in router:
makeAuthRouterwith/auth/me, JWT refresh/logout, session logout, and OAuth callbacks attachAuthmiddleware: auto-populatesreq.authwithout failing your routes- JWT and Session strategies with env-aware, secure-by-default cookies
- Optional JWT refresh rotation with reuse detection via pluggable refresh stores (Memory/Redis)
- Lightweight CORS (
makeCors) and rate limit (makeRateLimit) middlewares - Guards:
requireAuthGuard,requireRole,requirePermission - Standard error helpers with codes:
Errors - TypeScript declarations included
📦 Installation
npm install authkit-js
# Required peer dependencies
npm install express cookie-parser jsonwebtoken
# Optional (when you use them)
npm install ioredis google-auth-library node-fetch2FA helpers (TwoFA) are included out-of-the-box; no extra install is required.
⚡ Quick Usage
const express = require('express');
const cookieParser = require('cookie-parser');
const {
AuthKit, makeAuthRouter, attachAuth,
makeCors, makeRateLimit,
} = require('authkit-js');
const { MemorySessionStore } = require('authkit-js/lib/stores/memory');
const app = express();
app.use(express.json());
app.use(cookieParser());
// CORS (optional)
app.use(makeCors({ origin: ['http://localhost:5173'] }));
// Init authkit
const kit = new AuthKit({
jwt: { secret: 'super-secret' },
session: { store: new MemorySessionStore() },
});
// Attach auth context on every request (non-fatal)
app.use(attachAuth(kit));
// Auth router with simple rate limit (optional)
app.use('/auth', makeRateLimit({ capacity: 100, intervalMs: 60_000 }), makeAuthRouter(kit));
// Your login endpoint (example)
app.post('/login', async (req, res) => {
const user = { id: 1, email: req.body.email };
await kit.jwt.login(res, user);
res.json({ ok: true });
});
// Protected route
app.get('/me', async (req, res) => {
const ctx = await kit.authenticate(req);
if (!ctx || !ctx.user) return res.status(401).json({ error: 'Unauthorized' });
res.json({ user: ctx.user });
});
app.listen(3000, () => console.log('Server running on http://localhost:3000'));🔗 Social Login Setup
Google OAuth2
const { GoogleOAuthStrategy } = require('authkit-js/lib/strategies/oauth-google');
const kit = new AuthKit({
google: new GoogleOAuthStrategy({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: process.env.GOOGLE_REDIRECT_URI,
verify: async (profile) => ({ id: profile.sub, email: profile.email }),
})
});GitHub OAuth2
Facebook OAuth2
const { FacebookOAuthStrategy } = require('authkit-js/lib/strategies/oauth-facebook');
const kit = new AuthKit({
facebook: new FacebookOAuthStrategy({
clientId: process.env.FB_CLIENT_ID,
clientSecret: process.env.FB_CLIENT_SECRET,
redirectUri: process.env.FB_REDIRECT_URI,
verify: async (profile) => ({ id: profile.id, name: profile.name, email: profile.email }),
})
});Apple Sign In (OAuth/OIDC)
const { AppleOAuthStrategy } = require('authkit-js/lib/strategies/oauth-apple');
const kit = new AuthKit({
apple: new AppleOAuthStrategy({
clientId: process.env.APPLE_CLIENT_ID,
// For production, generate a JWT client secret signed with your Apple key
clientSecret: process.env.APPLE_CLIENT_SECRET,
redirectUri: process.env.APPLE_REDIRECT_URI,
verify: async (payload) => ({ id: payload.sub, email: payload.email }),
})
});🚦 Built-in Router Endpoints
GET /auth/me— returns{ user }when authenticatedPOST /auth/jwt/refresh— refreshes JWT using refresh cookiePOST /auth/jwt/logout— clears JWT cookiesPOST /auth/session/logout— clears session and CSRF cookies and deletes sessionGET /auth/oauth/googleand/auth/oauth/google/callbackGET /auth/oauth/githuband/auth/oauth/github/callbackGET /auth/oauth/facebookand/auth/oauth/facebook/callbackGET /auth/oauth/appleand/auth/oauth/apple/callback
Note: You still implement your own login that calls kit.jwt.login(res, user) or kit.session.login(res, user).
🔢 Two-Factor Authentication (TOTP) — Built-in Helpers
Use the TwoFA helper to generate a TOTP secret, show a QR code, and verify tokens during login.
const { TwoFA } = require('authkit-js');
// 1) Start 2FA setup — generate a secret and a QR code Data URL
app.get('/2fa/setup', async (req, res) => {
const username = String(req.query.username);
const secret = TwoFA.generateSecret(`MyApp (${username})`); // { base32, otpauth_url, ... }
const qr = await TwoFA.generateQRCodeDataURL(secret.otpauth_url);
// Persist `secret.base32` temporarily until user verifies a token
res.json({ secret: secret.base32, qr });
});
// 2) Enable 2FA — verify a token from user's authenticator app
app.post('/2fa/enable', (req, res) => {
const { secretBase32, token } = req.body;
const ok = TwoFA.verifyToken(secretBase32, token, 1); // window=1 for slight clock drift
if (!ok) return res.status(400).json({ error: 'Invalid token' });
// Mark 2FA enabled for the user, persist secretBase32
res.json({ ok: true });
});
// 3) During login — require a valid TOTP if the user has 2FA enabled
app.post('/login', async (req, res) => {
const { username, password, twoFactorToken } = req.body;
const user = await findUser(username);
if (!user || !(await checkPassword(user, password))) return res.status(401).json({ error: 'Invalid credentials' });
if (user.twoFAEnabled) {
const ok = TwoFA.verifyToken(user.twoFASecretBase32, twoFactorToken || '', 1);
if (!ok) return res.status(401).json({ error: 'Invalid 2FA token' });
}
await kit.jwt.login(res, { id: user.id, name: user.name });
res.json({ ok: true });
});These helpers are strategy-agnostic and work with both JWT and Session flows.
🔄 Refresh Token Rotation (JWT)
Enable rotation + reuse detection by providing a refresh store:
const { MemoryRefreshStore } = require('authkit-js');
const kit = new AuthKit({
jwt: {
secret: process.env.JWT_SECRET,
refreshStore: new MemoryRefreshStore(),
cookie: { env: process.env.NODE_ENV, crossSite: true }
}
});Use RedisRefreshStore for multi-instance deployments.
🛡 Guards & Errors
const { attachAuth, requireAuthGuard, requireRole, requirePermission, Errors } = require('authkit-js');
app.use(attachAuth(kit));
app.get('/admin', requireAuthGuard(), requireRole('admin'), (req, res) => res.send('ok'));
app.use((err, _req, res, _next) => res.status(err.status || 500).json({ code: err.code, error: err.message }));🌐 CORS & Rate Limit
const { makeCors, makeRateLimit } = require('authkit-js');
// Global CORS
app.use(makeCors({ origin: ['https://app.example.com'] }));
// Basic rate limit (per IP)
app.use('/auth', makeRateLimit({ capacity: 100, intervalMs: 60_000 }));🍪 Environment-Aware Cookies
Cookies default to httpOnly and:
secure=truein production (or whencrossSite=true)sameSite='lax'by default, or'none'whencrossSite=true
Configure per strategy:
new AuthKit({
jwt: {
secret: process.env.JWT_SECRET,
cookie: { env: process.env.NODE_ENV, crossSite: true }
},
session: {
store: new MemorySessionStore(),
cookie: { env: process.env.NODE_ENV, crossSite: false }
}
});const { GitHubOAuthStrategy } = require('authkit-js/lib/strategies/oauth-github');
const kit = new AuthKit({
github: new GitHubOAuthStrategy({
clientId: process.env.GH_CLIENT_ID,
clientSecret: process.env.GH_CLIENT_SECRET,
redirectUri: process.env.GH_REDIRECT_URI,
verify: async (profile) => ({ id: profile.id, login: profile.login }),
})
});🗄 Redis Session Store
const Redis = require('ioredis');
const { RedisSessionStore } = require('authkit-js/lib/stores/redis');
const redis = new Redis(process.env.REDIS_URL);
const kit = new AuthKit({
session: { store: new RedisSessionStore(redis) }
});🧪 Example App
A full working demo is in examples/express-server/:
cd examples/express-server
cp .env.example .env
node index.jsRoutes:
GET /auth/google→ Google loginGET /auth/github→ GitHub loginGET /me→ Protected profile route
📜 License
MIT © 2025 Shashi
