Sessions vs Tokens, the Un-bundled Koa Auth Landscape
Auth & Security Overview
Koa ships with no auth layer, so you choose your own strategy. This lesson maps the landscape — sessions, JWTs, OAuth, and hosted providers — so you can pick the right tool for your use-case.
What you'll learn
- Distinguish session-based auth from token-based auth
- Identify the ecosystem packages that fill each auth role in Koa
- Decide when to use a hosted provider instead of rolling your own
Unlike Express, Koa ships with no built-in auth. That is a feature, not an omission: you compose exactly the pieces you need rather than working around ones you don’t.
Sessions vs Tokens
Two schools of thought dominate web auth:
| Approach | How state is stored | Best for |
|---|---|---|
| Session (cookie) | Server-side store; cookie holds only an ID | Traditional web apps, SSR |
| JWT (token) | Client holds the token; server is stateless | SPAs, mobile clients, microservices |
| Hybrid | Short-lived JWT + refresh token in httpOnly cookie | Best of both worlds |
Session auth gives you instant revocation — delete the session row and the user is logged out. The trade-off is that every request hits the store (memory, Redis, etc.).
JWTs are self-contained: the server can verify a token without a database round-trip. The trade-off is that tokens are valid until they expire, so revocation requires a blocklist (which re-introduces state).
The Koa Auth Ecosystem
| Role | Package |
|---|---|
| Sessions | koa-session |
| Signed cookies | app.keys (built-in) |
| JWT middleware | koa-jwt + jsonwebtoken |
| Strategy-based auth | koa-passport |
| Social / OAuth | Passport strategies (passport-google-oauth20, etc.) |
| Security headers | koa-helmet |
| CORS | @koa/cors |
| CSRF protection | koa-csrf |
| Rate limiting | koa-ratelimit |
Hosted Providers
For production apps, delegating auth to a hosted provider (Auth0, Clerk,
Supabase Auth, Firebase Auth) often reduces risk and maintenance burden. Your
Koa server verifies the JWT the provider issues — koa-jwt handles that
verification in one middleware call.
Password Hashing
Whenever you store passwords yourself, use bcrypt (bcryptjs) or
argon2. Never store plaintext or use fast hashes (MD5, SHA-1, SHA-256
without a work factor). Both bcrypt and argon2 are slow by design.
import bcrypt from "bcryptjs";
// on registration
const hash = await bcrypt.hash(plainPassword, 12);
// on login
const ok = await bcrypt.compare(plainPassword, storedHash); Up Next
Set up server-side sessions with koa-session and walk through a complete
login/logout flow.