Go to file
Hyojin Ahn bb3bb7f03a 임시 변경 2026-06-19 09:06:41 -04:00
public client 만 남기고 정리 2026-06-16 11:26:53 -04:00
src 임시 변경 2026-06-19 09:06:41 -04:00
.env 서버 환경에 맞게 config 수정 2026-06-18 08:28:14 -04:00
.env.example client 만 남기고 정리 2026-06-16 11:26:53 -04:00
.gitignore 서버 환경에 맞게 config 수정 2026-06-18 08:28:14 -04:00
LICENSE init 2026-01-23 13:59:23 -05:00
README.md client 만 남기고 정리 2026-06-16 11:26:53 -04:00
eslint.config.js client 만 남기고 정리 2026-06-16 11:26:53 -04:00
index.html client 만 남기고 정리 2026-06-16 11:26:53 -04:00
package-lock.json client 만 남기고 정리 2026-06-16 11:26:53 -04:00
package.json client 만 남기고 정리 2026-06-16 11:26:53 -04:00
vite.config.js 서버 환경에 맞게 config 수정 2026-06-18 08:28:14 -04:00

README.md

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.js exposes authUrl() and oprUrl().
  • Auth calls (/auth/login, /auth/me, /auth/logout, /auth/token/refresh) go through authUrl() → auth service.
  • Data calls go through oprUrl() → opr/data service. See src/features/products/ProductsPage.jsx for 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. role drives 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.jsx provides RequireAuth and RequireRole.
  • <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 role strings to whatever your backend returns (the reference uses lowercase "user" / "admin").
  • The dead App.css (Vite starter leftover) was removed.