Files
ai-teacher/specs/003-basic-login/research.md
T
2026-04-06 14:29:53 +02:00

4.1 KiB

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}")