Add simple auth
This commit is contained in:
@@ -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}")` |
|
||||
Reference in New Issue
Block a user