KEM 2.0 - frontend
Vývoj front-endové části druhé verze Krajského energetického managementu započal začátkem července roku 2024. První verze byla vyvíjena pomocí frameworku Django, který se neosvědčil (nezkušenost s daným frameworkem, dlouhá prodleva před vykreslením obrazovek, nepřehledné UI, ...). Proto se rozhodlo jít cestou samostatného frontendu a backendu.
Aplikace je vyvíjena za pomocí JS knihovny React s využitím TypeScript. Přihlášení uživatelů je řešeno pomocí client-side JS Keycloak knihovny keycloak-js. Data jsou získávána z API, pro ověření je nutné předat Bearer token uživatele vygenerovaný knihovnou keycloak-js.
Použité technologie a knihovny
- Node.js (testováno s verzí 18.10.0) - pro použití správce balíčků npm
- Vite.js pro sestavení front-end projektu
- React.js (18.3.1) knihovna pro tvorbu UI (s využitím TypeScript)
- OpenAPI Generator (7.7.0) pro vygenerování tříd s definicí API endpointů s typováním
Veškeré knihovny a pluginy použité v projektu jsou udržovány v souboru package.json.
Ke zmínění:
- axios → promise-based HTTP Client
- Material UI → sada React UI komponent
- formik → pro snadnější práci s formuláři (pro validační schéma použita knihovna yup)
- react-toastify → informační vyskakovací okna (úspěšné uložení, načítání dat,...)
Instalace a spuštění
Požadavky
- Node.js
- Java
- OpenAPI Generator
7.7.0, instalace:
npm install @openapitools/openapi-generator-cli -g
openapi-generator-cli version-manager set 7.7.0
Kroky instalace
- Stáhni projekt a přejdi do složky app.
- Nainstaluj všechny potřebné balíčky pomocí:
npm install
Po úspěšné instalaci se vytvoří složka node_modules.
- Vygeneruj API klienta pomocí nástroje OpenAPI Generator:
npm run fetch-openapistáhne aktuální openapi.json (uprav adresu dle toho, kde ti běží api)
poté lze pomocí skriptu vygenerovat z tohoto openapi.json API klienta:
npm run generate-api
npm run update-api
- Spusť vývojový režim aplikace:
npm run dev
- Build aplikace:
npm run build
.env proměnné
V projektu se používá načítání proměnných ze souboru .env. Ten se musí nacházet na úrovni /app. Každá proměnná musí obsahovat prefix VITE_. Definování adresy, kde se nachází API, provedeme pomocí proměnné VITE_API_URL.
Dále musíme definovat Keycloak proměnné:
VITE_KEYCLOAK_URL
VITE_KEYCLOAK_REALM
VITE_KEYCLOAK_CLIENTID
Příklad souboru .env je dostupný v projektu pod názvem env.local.example (soubor s příponou .local je zahrnut v .gitignore).
Souborová struktura
V kořenovém adresáři najdeme soubory pro nastavení docker-compose, nginx a GitLab CI/CD. Ve složce app najdeme projekt založený pomocí nástroje Vite, kde byla využita knihovna React společně s TypeScriptem.
- app - obsahuje nastavení projektu a implementaci React aplikace.
- openapi - obsahuje soubor
openapi.json, který slouží pro vygenerování klienta - public - obrázky a loga.
- index.html - obsahuje skript odkazující na komponentu
main.tsx, kde dochází k napojení na React knihovnu. - package.json - balíčky včetně jejich verze, které projekt využívá (devDependencies pro vývoj).
- package-lock.json - uchovává přesné informace o instalovaných balíčcích.
- src
- components - jednotlivé části aplikace rozdělené do komponent.
- generated - vygenerované třídy s definicí API endpointů (
npm run generate-api). - hooks - vlastní hooky (např.
useAuth,useGlobalModal). - pages - komponenty pro vykreslení hlavních obrazovek aplikace.
- providers - všechny poskytovatelé (auth, globalModal, organizations,...).
- services/api - napojení na vygenerovaného klienta a definice axios interceptorů.
- utils - pomocné funkce a komponenty.
- constants.tsx - definice konstant (např.
SIDEBAR_WIDTH). - App.tsx - definice routes a dalších potřebných kontejnerů/providerů.
- mui-theme.ts - téma pro MUI knihovnu (paleta barev, stylizace komponent pro design projektu).
- main.tsx - napojení na React knihovnu.
- openapi - obsahuje soubor
Formátování kódu
Vývoj probíhá ve Visual Studio Code s nainstalovaným rozšířením Prettier - Code formatter, pomocí config souboru .prettierrc je nastavena šířka tabu na 4 mezery. Pro zformátování importů je využívána zkratka SHIFT + CTRL + O a kódu SHIFT + ALT + F. Do budoucna lze pro jednoduchost a konzistentnost používat např. Husky.
Využití knihovny keycloak-js
V aplikaci je použita knihovna keycloak-js, která umožňuje použití Keycloaku na straně klienta. Konfigurace keycloak instance najdeme v souboru app/src/keycloak.config.ts.
V komponentě AuthorizationProvider se volá metoda init, která kontroluje aktivní session uživatele a přesměruje jej na přihlašovací formulář, pokud není přihlášen. Při úspěšném přihlášení je token automaticky připojen k axios interceptoru, který ho přidá do každého požadavku.
Uživatelé v aplikaci a jejich inicializace
Jako identity management se využívá Keycloak, který uchovává základní údaje o uživateli. Po přihlášení do aplikace se uživatel inicializuje pomocí API endpointu initUser, který vytvoří session s jeho právy.
Práva uživatele
Práva uživatele jsou udržována na úrovni aplikace v databázi. Na základě odpovědi z API endpointu se rozhoduje o vykreslení různých pohledů.
Token a jeho životnost
Životnost tokenu uživatele je nastavena na 15 minut. Automatické obnovení tokenu je implementováno pomocí axios interceptoru, který token obnovuje, pokud zbývá minuta do jeho vypršení.
Odhlášení uživatele
Odhlášení je implementováno pomocí funkce logout.ts, která zničí session na úrovni Keycloaku a také z aplikace.
K zamyšlení
- Pokud uživatel uzavře prohlížeč, session zůstane aktivní a lze ji zneužít, pokud není správně ošetřena.
- Při nastavení Session Idle Timeoutu je důležité zvážit komunikaci s Keycloakem, která probíhá jen při načtení stránky nebo obnovení tokenu.