2.8 KiB
goi-web client
Vite + React front end for JWT authentication using HttpOnly cookies, intended to run
against a Spring Boot backend. This is the standalone client extracted from the original
monorepo (the Express apps/server and monorepo wrapper were removed).
Run
npm install
npm run dev # http://localhost:5173
The dev server proxies API calls to the backend, so make sure your Spring Boot app is
running (default http://localhost:8080).
How requests are routed (CORS-free dev)
.env uses relative base URLs:
VITE_AUTH_SERVICE_URL=/auth-service
VITE_OPR_API_URL=/opr-rest-api
vite.config.js proxies those prefixes to the backend:
/auth-service/* -> http://localhost:8080/auth-service/*
/opr-rest-api/* -> http://localhost:8083/opr-rest-api/*
Because the browser only ever talks to localhost:5173 (same origin), there is no CORS in
development and the HttpOnly cookies attach normally. Change the BACKEND constant in
vite.config.js if your backend port differs.
If you prefer to call the backend directly (no proxy), switch .env to absolute URLs
(commented examples are in the file) and configure CORS on the backend:
allowCredentials = true with an explicit origin (http://localhost:5173) — * is not
allowed together with credentials.
auth vs data calls
src/lib/endpoints.jsexposesauthUrl()andoprUrl().- Auth calls (
/auth/login,/auth/me,/auth/logout,/auth/token/refresh) go throughauthUrl()→ auth service. - Data calls go through
oprUrl()→ opr/data service. Seesrc/features/products/ProductsPage.jsxfor an example. Never fetch data from the auth URL.
Backend contract the client expects
POST /auth-service/auth/login— sets HttpOnly cookies, returns the user object.GET /auth-service/auth/me— returns{ authenticated: true, role, firstName, lastName, ... }when logged in.roledrives the client-side role checks.POST /auth-service/auth/logout— clears cookies.POST /auth-service/auth/token/refresh— rotates the access token (called automatically on 401).GET /opr-rest-api/products(example) — returns{ status, created, data: [...] }.
Role-based access (RBAC)
src/auth/authGuard.jsxprovidesRequireAuthandRequireRole.<RequireRole role="admin">(or an array of roles) guards a route; the sidebar shows the Admin link only to admins.- The front-end guard is UX only. Always enforce roles on the server too
(e.g. Spring Security
@PreAuthorize("hasRole('ADMIN')")). The client can be tampered with.
Notes
- Match the
rolestrings to whatever your backend returns (the reference uses lowercase"user"/"admin"). - The dead
App.css(Vite starter leftover) was removed.