a9ef4cf629
Rewrites all 7 backend ADRs from a custom structure to the MADR 2.1.2 template required by the VS Code ADR Manager extension: bullet metadata (Status/Date), standardised section headings, "Chosen option: X, because Y" wording, and explicit Pros/Cons blocks per option.
54 lines
2.3 KiB
Markdown
54 lines
2.3 KiB
Markdown
# Use JWT for API authentication
|
|
|
|
* Status: accepted
|
|
* Date: 2026-04-26
|
|
|
|
## Context and Problem Statement
|
|
|
|
The API must authenticate requests from the Angular frontend. How should user identity be verified on each request?
|
|
|
|
## Decision Drivers
|
|
|
|
* Application is currently single-instance with no horizontal scaling requirement.
|
|
* Frontend already uses token-based auth (stores JWT in `localStorage` — see frontend ADR 0005).
|
|
* Simplicity of operation is preferred over session infrastructure.
|
|
|
|
## Considered Options
|
|
|
|
* JWT (JSON Web Tokens) with `express-jwt`
|
|
* Session-based authentication
|
|
|
|
## Decision Outcome
|
|
|
|
Chosen option: "JWT", because it is stateless (no session store needed), aligns with the frontend's existing token-based auth flow, and is simpler to operate for a single-instance deployment.
|
|
|
|
Tokens are issued on successful login (`jsonwebtoken` library, `bcrypt` for password hashing). Incoming requests are validated by `express-jwt`, which populates `req.auth` with the decoded payload. The `src/middlewares/auth.js` middleware wraps `express-jwt` and handles role-based access control (`Admin` role required for protected admin routes). The frontend sends tokens as `Authorization: Token <jwt>`.
|
|
|
|
### Positive Consequences
|
|
|
|
* Stateless — no session store needed. Horizontally scalable without sticky sessions.
|
|
* Single middleware handles auth for all routes.
|
|
|
|
### Negative Consequences
|
|
|
|
* Tokens cannot be invalidated server-side before expiry. Acceptable for this use case (internal application, low revocation risk).
|
|
|
|
## Pros and Cons of the Options
|
|
|
|
### JWT
|
|
|
|
* Good, because stateless — no session store infrastructure.
|
|
* Good, because works seamlessly with the frontend's `localStorage`-based token flow.
|
|
* Bad, because revocation requires token blacklisting, which adds state.
|
|
|
|
### Session-based authentication
|
|
|
|
* Good, because sessions can be invalidated immediately server-side.
|
|
* Bad, because requires a session store (Redis or database-backed) — adds infrastructure complexity.
|
|
* Bad, because sticky sessions or a shared store are needed in multi-instance deployments.
|
|
|
|
## Links
|
|
|
|
* Related to frontend [ADR 0005](../../adastra_app/docs/decisions/0005-jwt-authentication-localstorage.md)
|
|
* Security note: passwords are hashed with `bcrypt`. The JWT secret must be kept in environment configuration, never committed.
|