AdonisJS Authentication: Choosing Between Session and Token Guards
A decision guide for choosing between session and token (JWT) authentication in AdonisJS, with constraints, a compact comparison table, trade‑offs, and a concrete validation checklist.
15 Apr 2026, 05:53 UTC

Decision: Session vs Token Authentication in AdonisJS
When building an AdonisJS application you must decide how users prove their identity. The choice hinges on the client type, required logout speed, and how you handle token revocation.
Constraints and Decision
The decision is constrained by three factors:
- Client environment – browser‑rendered pages, same‑site apps, or separate clients such as mobile or SPA front‑ends.
- Revoke requirement – do you need instant logout or can you rely on token expiration?
- Infrastructure – do you have a reliable session store (Redis, database) or prefer a stateless approach?
If you answer “browser app with immediate logout” and “available session store”, session authentication is the pragmatic choice. If you answer “SPA, mobile, or micro‑service API” and “stateless requests”, token (JWT) authentication fits better.
Compact Comparison
| Aspect | Session Authentication | Token (JWT) Authentication |
|---|---|---|
| State handling | Server‑side state kept in a store (Redis, DB). | Client holds the token; server is stateless. |
| Revocation | Immediate – delete the session record or invalidate the cookie. | Requires blacklist or short‑lived token + refresh flow. |
| Scalability | Depends on store availability and clustering; Redis scales well but adds a dependency. | Scales horizontally without extra store; only signature verification needed. |
| Security model | Cookie‑based, can be set HttpOnly & SameSite to mitigate XSS/CSRF. | Bearer token in Authorization header; stored in memory, localStorage, or cookie – XSS risk if not protected. |
| Typical use cases | Server‑rendered pages, same‑site web apps, apps needing instant logout. | SPAs, mobile clients, cross‑service APIs, environments where the client cannot maintain a server session. |
Trade‑offs
Session auth simplifies revocation and provides a clear logout mechanism, but it couples your deployment to a highly available session store. Losing Redis or the database session table can log users out or break failover.
Token auth removes the per‑request store dependency, which is attractive for horizontally scaled APIs. However, token leakage, expiration design, refresh strategy, and revocation become application responsibilities. Short‑lived access tokens without a clear refresh and revocation plan can create either usability problems or long‑lived stolen‑token risk.
Concrete Validation Approach
Regardless of the guard you choose, validate the implementation with the following checks. Run these against a staging environment that mirrors production configuration.
- Login flow – Submit valid credentials to the login endpoint. Expect a 200 response with either a session cookie (session guard) or an access token (token guard).
- Protected route access – Request a guarded route with the issued credential. Expect 200 and the protected resource.
- Missing credential rejection – Request the same guarded route without the cookie or token. Expect 401.
- Expired credential rejection – Wait for the session TTL or token expiry, then replay the credential. Expect 401.
- Tampered credential rejection – Modify the session cookie signature or the JWT payload/signature and replay. Expect 401.
- Revocation / logout – Call the logout endpoint (session) or add the token to a revocation list (token). Replay the credential; expect 401.
For session guards, also verify that the cookie is set with HttpOnly, Secure (in production), and an appropriate SameSite value. For token guards, confirm that the Authorization: Bearer header is required and that refresh tokens (if used) are rotated and stored securely.
Version Note
AdonisJS v6 (the current major release as of 2026) provides the @adonisjs/auth package with session and jwt guards. Guard names, configuration keys, and middleware signatures may differ in earlier major versions. Always inspect config/auth.ts and the installed package versions before copying examples.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.