Auth middleware у Bun.js: JWT, sessions, API keys і multi-tenant context без хаосу
Практичний deep dive по auth middleware у Bun.js: як будувати JWT, session і API-key перевірки, де тримати tenant context, як розділяти 401/403, що кешувати, як уникати витоку токенів і які best practices брати з OWASP, Hono та Elysia.

Bun.js Middleware Production Guide 2026
Серія про production middleware у Bun.js: огляд, безпека, performance, observability, rate limiting, body parsing, WebSocket/SSE і тестування request pipeline.
Усі статті в цьому гайді
01
Bun.js middleware у 2026: overview, best practices і анти-патерни
Базова ментальна модель middleware у native Bun, Hono та Elysia, з прикладами, оптимізацією і roadmap наступних deep dive статей.
02
Auth middleware у Bun.js: JWT, sessions, API keys і multi-tenant контекст
Як правильно будувати auth middleware у Bun: порядок перевірок, cache, token rotation, tenant context, помилки 401/403 і тестування.
03
Rate limiting у Bun.js: in-memory, Redis, sliding window і edge cases
Детальний розбір rate limiting для Bun API: алгоритми, Redis, distributed limits, abuse protection і graceful degradation.
04
Observability middleware у Bun.js: logs, request id, tracing і latency budgets
Як додати request id, structured logs, timing headers, OpenTelemetry-подібний flow і не перетворити логування на bottleneck.
05
Body parsing і validation у Bun.js: JSON, uploads, streams і payload limits
Як безпечно читати body у Bun, де ставити limits, як не зламати streams, uploads, idempotency і schema validation.
Найнебезпечніші auth баги рідко виглядають як “користувач без токена зайшов у систему”. Частіше токен валідний, сесія існує, API key справжній, але middleware прив'язав request не до того tenant, не перевірив scope, переплутав 401 і 403, або залогував секрет.
Bun дає швидкий HTTP layer, але auth - це не runtime trick. Це contract: які credentials приймаються, де вони зберігаються, як валідовуються, хто створює user context, де починається authorization і як усе це тестується.
У цій статті ми не будемо робити “ще один login tutorial”. Ми розберемо production-патерни auth middleware для Bun API.
Це другий chapter серії про Bun middleware. Перший дав загальну модель pipeline, цей фокусується на auth шарі: де він має бути тонким, де йому потрібен storage, а де він уже не middleware.
decode без verify не є auth. [4]Немає одного “правильного” auth механізму. Є різні trade-offs: stateless перевірка, контрольований logout, machine-to-machine доступ, rotation, revocation і UX.
| Механізм | Коли підходить | Що перевіряти | Головний ризик |
|---|---|---|---|
| JWT access token | Mobile/API clients, service-to-service, distributed verification | exp, iss, aud, signature, algorithm, subject, scopes | Важка revocation модель і спокуса робити довгоживучі tokens |
| Server-side session | Browser apps, dashboards, SaaS, де потрібен контрольований logout | Session id у secure cookie, session store, expiry, device/risk metadata | Session fixation, insecure cookies, weak store cleanup |
| API key | Integrations, webhooks, internal automations, machine clients | Hashed key lookup, scope, owner, environment, last used, rotation | Plaintext key storage і ключі без scopes або expiry policy |
| Hybrid | BFF, enterprise SaaS, admin panels plus public API | Session для browser, JWT/API keys для services | Різні auth моделі без єдиного audit і error contract |
JWT, sessions і API keys відповідають на різні задачі: stateless access, browser logout control і machine-to-machine доступ.
Скріншот секції credential-mapВисновок
Для browser SaaS зазвичай починайте із sessions. Для external API - API keys або короткоживучі JWT. Для distributed systems - JWT плюс revocation або introspection там, де ризик високий.
У native Bun.serve ви можете зробити auth layer без framework. Важливо не мутувати глобальний state і не ховати context у module-level змінних. Передавайте context явно: або через wrapper, або через власний AppRequestContext.
Один з простих патернів:
type AuthContext = {
subjectId: string;
tenantId: string;
scopes: string[];
method: "jwt" | "session" | "api-key";
};
type AppContext = { auth: AuthContext | null; requestId: string };
type Handler = (req: Request, ctx: AppContext) => Promise<Response> | Response;
type Middleware = (next: Handler) => Handler;
const unauthorized = () =>
Response.json({ error: "unauthorized" }, { status: 401 });
const withAuth: Middleware = (next) => async (req, ctx) => {
const header = req.headers.get("authorization");
if (!header?.startsWith("Bearer ")) return unauthorized();
const token = header.slice("Bearer ".length);
const auth = await verifyAccessToken(token);
if (!auth) return unauthorized();
return next(req, { ...ctx, auth });
};
Bun.serve({
fetch: withAuth(async (_req, ctx) => {
return Response.json({ subjectId: ctx.auth?.subjectId });
}),
});Цей приклад навмисно не показує реалізацію verifyAccessToken, бо вона залежить від вашого JWT/session/API-key рішення. Важливий shape: middleware не читає business resource, не робить permissions на invoice/project/order і не створює side effects. Він створює auth context або повертає 401.
Що тут важливо
Контекст має бути request-scoped і явний. Якщо auth state живе у глобальній змінній, singleton або mutable module object, ви створюєте ризик leakage між запитами.
Якщо ви не хочете писати весь auth layer руками, Hono і Elysia мають готові primitives. Але готовий middleware не скасовує ваші правила issuer, audience, scopes, tenant і error contract.
Honojwt()перевіряє token і кладе payload у context черезc.get('jwtPayload'); middleware шукаєAuthorizationheader, якщо не налаштовано cookie option. [2]
HonobearerAuth()підходить для API tokens і даєverifyToken, custom errors, realm, prefix і headerName. [3]
Висновок
Built-in middleware варто брати для parsing і базової verification. Але tenant resolution, scopes, audit і business authorization залишаються вашим application design.
У SaaS найчастіша auth-помилка виглядає не як “немає токена”, а як “valid user зміг працювати в чужому tenant”. Причина проста: middleware взяв x-tenant-id з request і не перевірив, що subject справді має доступ до цього tenant.
Tenant context має виводитись із credential або перевірятися проти server-side membership. Якщо користувач може перемикати tenant, header або path param може бути input, але не authority.
Правильний flow: verify credential, отримати subject, отримати allowed tenants/scopes, зіставити requested tenant із allowed list, прикріпити resolved tenant у context. Якщо tenant не дозволений, це вже 403, а не 401.
x-tenant-id як source of truth.Tenant має бути resolved і перевірений сервером. Header або path param може бути запитом користувача, але не доказом доступу.
Скріншот секції multi-tenant-contextНеправильні auth errors створюють проблеми для клієнтів, logs і security review. У Bun pipeline краще одразу зафіксувати contract.
Credential відсутній або невалідний
Немає Authorization, token malformed, signature invalid, session expired, API key не знайдено. Клієнт має розуміти, що треба пройти authentication.
Credential валідний, але дія заборонена
Subject authenticated, але не має tenant access, scope, role або permission для ресурсу.
Auth abuse або rate limit
Brute force, занадто багато invalid token attempts, API key abuse. Не змішуйте це з 401, бо клієнт і monitoring мають реагувати інакше.
Auth infrastructure failure
Session store, JWKS endpoint, Redis або DB недоступні. Для деяких routes краще fail closed, для public degraded flows може бути інша policy.
Висновок
Єдиний error format важливий так само, як і правильний status code. Клієнт, monitoring і security tooling мають бачити стабільний contract.
Auth часто стає найважчим middleware, бо тягне crypto, storage, tenant resolution і audit. Прискорення починається не з алгоритму, а з маршрутизації й caching policy.
Добре: public/system routes поза auth pipeline
/health, /ready, static assets і public docs не повинні робити token parsing або session lookup.
Обережно: DB lookup на кожен JWT
Якщо кожен JWT все одно іде в DB для перевірки, подумайте, чи JWT дає вам користь проти session id. Можливо, вам потрібна session/introspection модель.
Добре: короткий cache для stable auth metadata
Tenant membership, API key owner і JWKS keys можна кешувати з чітким TTL та revocation story.
Обережно: long-lived cache permissions
Permissions змінюються. Якщо кеш живе довше за security expectation, користувач зберігає доступ після revoke.
Висновок
Auth performance не має конфліктувати з revocation. Якщо кешуєте, одразу визначайте TTL, invalidation і high-risk fallback.
Ці помилки не специфічні тільки для Bun, але в Bun-проєктах вони часто з'являються під виглядом “ми просто швидко написали thin middleware”.
Використовувати jwt.decode() або читати payload без signature verification.
Не перевіряти exp, iss, aud і algorithm для JWT.
Зберігати access token у localStorage для browser app без чіткої XSS threat model.
Логувати Authorization, cookies, refresh token або full API key.
Зберігати API keys у plaintext замість hash + prefix lookup.
Давати API key без scopes, owner, environment і rotation policy.
Вважати x-tenant-id авторитетним джерелом tenant context.
Повертати 200 з { error: ... } для auth failures.
Змішувати authentication, tenant membership і resource authorization в один глобальний middleware.
Рев'ю правило
Якщо middleware не можна пояснити як маленький state machine з 401/403/next, він уже занадто складний або бере на себе не свою відповідальність.
Перед staging або security review пройдіться по цьому списку. Він спеціально сформульований як інженерний checklist, а не як загальні поради.
Credential extraction один раз
Один шар читає Authorization/cookies/API key і передає результат далі як typed context.
JWT verification повна
Signature, algorithm, expiry, issuer, audience, subject і clock skew policy перевірені.
Session cookies захищені
httpOnly, secure, sameSite, narrow path, TTL і HTTPS policy зафіксовані.
API keys не зберігаються відкрито
У базі тільки hash, key prefix, owner, scopes, last used, created/revoked metadata.
Tenant context перевіряється
Requested tenant звіряється з membership/scopes subject, а не приймається з header як факт.
401 і 403 розділені
Missing/invalid credential дає 401; valid credential без права на дію дає 403.
Secrets redacted
Logs, tracing, error reports і analytics не містять tokens, cookies, API keys або PII.
Revocation story існує
Для JWT, sessions і API keys є зрозуміла модель відкликання, rotation і forced logout.
У Bun легко написати швидкий auth wrapper. Складніше написати auth middleware, який не змішує authentication і authorization, не тече між tenants, не логить секрети, не створює зайвий DB lookup на кожен request і має нормальний error contract.
JWT, sessions і API keys не конкурують як “кращий” і “гірший” варіант. Вони відповідають на різні задачі. JWT зручний для stateless access, sessions - для browser UX і контрольованого logout, API keys - для integrations. У production часто потрібен hybrid, але з єдиним audit і policy шаром.
Правильний Bun auth pipeline виглядає просто: extract, verify, resolve subject, resolve tenant, attach context, continue або reject. Усе інше має бути явно спроєктовано, протестовано і виміряно.
Не завжди. JWT корисний для stateless access і service-to-service сценаріїв, але складніший для revocation. Sessions краще підходять для browser SaaS, де потрібен контрольований logout, secure cookies і session store. Вибір залежить від клієнта, threat model і revocation вимог. [4][5]
Так. Native `Bun.serve` дозволяє написати auth як композицію функцій навколо `Request`/`Response`. Але ви самі відповідаєте за context, errors, order, tests і security policy.
`401` для missing/invalid credential: немає token, session expired, invalid signature, API key не знайдено. `403` для валідного credential без permission, tenant access або required scope.
У request-scoped auth context після перевірки credential і membership. Не довіряйте `x-tenant-id` як source of truth. Header або path param може бути requested tenant, але middleware має перевірити доступ subject до нього.
Ні. Authorization headers, cookies, refresh tokens і API keys мають бути redacted. Логуйте request id, subject id, tenant id, auth method і error class, але не credential.
Показуйте повний API key тільки один раз при створенні, зберігайте hash, тримайте короткий prefix для lookup, додавайте owner, scopes, environment, created/last used/revoked metadata і rotation policy.
Джерела підтверджують поведінку Bun Cookie API, Hono/Elysia auth middleware/plugins і security baseline для JWT та session management.
PAS7 Studio може допомогти спроєктувати auth middleware для Bun, Hono або Elysia: JWT/session/API-key модель, tenant context, scopes, secure cookies, rotation, observability і security review.
Це особливо корисно для SaaS, internal platforms, B2B API і міграцій з Express/Fastify, де auth behavior уже розповзся по middleware, guards і helpers.
Auth middleware у Bun.js: JWT, sessions, API keys і multi-tenant контекст
Пов'язані статті
Скільки коштує розробка AI асистента у 2026: RAG чатбот, база знань, CRM, Telegram та підтримка
Практичний гід для бізнесу: від чого залежить ціна розробки AI асистента у 2026 році, що входить у RAG чатбот, інтеграції з CRM, Telegram, guardrails, оцінювання, моніторинг і супровід.
AI для розробки лендінгів: де він реально прискорює запуск, а де псує конверсію
Дослідження про використання AI у розробці лендінгів: v0, Webflow AI, Builder.io, Framer-подібні AI builders, генерація UX, copy, SEO, персоналізація, A/B тести, ризики шаблонності, безпеки, доступності та технічного боргу.
AI SEO / GEO у 2026: ваші наступні клієнти — не люди, а агенти
Пошук зміщується від кліків до відповідей. Боти та AI-агенти сканують, цитують, рекомендують і дедалі частіше купують. Дізнайтесь, що таке AI SEO / GEO, чому класичного SEO вже недостатньо, і як PAS7 Studio допомагає брендам перемагати у «агентному» вебі.
Найпотужніший чіп від Apple? M5 Pro і M5 Max б'ють рекорди
Аналітичний розбір Apple M5 Pro і M5 Max станом на березень 2026 року. Пояснюємо, чому ці чіпи можна вважати найпотужнішими професійними ноутбучними SoC від Apple, як вони виглядають на тлі M4 Pro, M4 Max, M1 Pro, M1 Max і що показують у порівнянні з актуальними Intel та AMD.
Професійна розробка для вашого бізнесу
Створюємо сучасні веб-рішення та боти для бізнесу. Дізнайтеся, як ми можемо допомогти вам досягти цілей.