Add simple auth

This commit is contained in:
Adrien
2026-04-06 14:29:53 +02:00
parent e5d53b4e80
commit 0cf318f0a7
21 changed files with 1083 additions and 31 deletions
+64
View File
@@ -0,0 +1,64 @@
# Research: Basic Login Protection
**Feature**: 003-basic-login
**Date**: 2026-04-06
## Finding 1: Backend Auth Mechanism — Already Implemented
**Decision**: Keep existing HTTP Basic Auth (Spring Security, `SecurityConfig.java`).
**Rationale**: Spring Security with HTTP Basic is already configured and working. The backend validates credentials on every API request. There is nothing to add except making the username configurable and adding a credential-check endpoint.
**Alternatives considered**: Form-based login with server-side sessions — rejected because it adds session management complexity on the backend that is unnecessary for an SPA using HTTP Basic.
---
## Finding 2: Frontend Credential Storage — sessionStorage
**Decision**: Store entered username and password in browser `sessionStorage` via a Pinia store.
**Rationale**:
- `sessionStorage` persists across page refreshes (same tab) but is cleared when the tab is closed — this matches the expected session behavior (SC-004) without needing a server-side session or JWT.
- Simpler than `localStorage` (no explicit logout needed to clear on browser close).
- No additional dependencies required.
**Alternatives considered**:
- `localStorage` — rejected: credentials would persist indefinitely across browser sessions, which is unexpected for a "login" flow.
- In-memory (reactive ref only) — rejected: credentials lost on page refresh, violating SC-004.
- Cookie-based session (server-side) — rejected: requires CSRF protection, session store, and more backend complexity; violates KISS.
---
## Finding 3: Credential Verification — Lightweight Backend Endpoint
**Decision**: Add `GET /api/v1/auth/check` that returns `200 OK` with `{"username": "..."}` for authenticated requests.
**Rationale**: The frontend needs a way to verify that stored credentials are valid when the app loads (e.g., after a refresh). Without this, the first real API call would fail with a 401 and force a re-login on every refresh if credentials changed. This endpoint is protected by Spring Security like all others — no special logic needed.
**Alternatives considered**:
- Re-use any existing GET endpoint (e.g., `GET /api/v1/books`) — rejected: couples auth verification to a business endpoint; semantically wrong and fragile.
- Intercept 401s globally and redirect to login — used as a fallback but not sufficient alone: the user would see a flash of the main UI before being redirected.
---
## Finding 4: Axios Integration — Request Interceptor
**Decision**: Replace the hardcoded `auth` field in `api.ts` with a dynamic request interceptor that reads credentials from the Pinia auth store at request time.
**Rationale**: The current `api.ts` sets `auth: { username, password }` once at module initialisation from env vars. This must change so the login form's entered credentials are used. A request interceptor reads the store on every call, enabling logout (clear store → next request gets no credentials → 401 → redirect to login).
**Alternatives considered**:
- Recreate the axios instance after login — rejected: all existing services import the singleton `api`; recreating would require updating every import.
---
## Finding 5: Backend Username Configurability
**Decision**: Read username from `${app.auth.username:neurosurgeon}` in `SecurityConfig.java` (with "neurosurgeon" as default).
**Rationale**: The spec (FR-012) requires credentials to be configurable. Currently the password is configurable via env var but the username is hardcoded. Adding a `@Value`-injected username field is a one-line change.
**Alternatives considered**: None — this is the Spring Boot idiomatic approach already used for the password.
---
## Summary of Unknowns Resolved
| Unknown | Resolution |
|---------|-----------|
| Where to store credentials on the frontend | `sessionStorage` via Pinia |
| How to verify credentials after page refresh | `GET /api/v1/auth/check` endpoint |
| How to inject credentials into axios | Request interceptor in `api.ts` |
| How to handle 401s globally | Response interceptor → redirect to `/login` |
| Backend username configurability | `@Value("${app.auth.username:neurosurgeon}")` |