From aa122113ade36f02dc8fdbebdf1232b5c4b8742c Mon Sep 17 00:00:00 2001 From: Kamal Wickramanayake Date: Fri, 3 Jul 2026 19:02:36 +0530 Subject: Microservice sample projects --- .../04-react-app/src/contexts/AuthContext.jsx | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 microservices/04-react-app/src/contexts/AuthContext.jsx (limited to 'microservices/04-react-app/src/contexts') diff --git a/microservices/04-react-app/src/contexts/AuthContext.jsx b/microservices/04-react-app/src/contexts/AuthContext.jsx new file mode 100644 index 0000000..9bb5937 --- /dev/null +++ b/microservices/04-react-app/src/contexts/AuthContext.jsx @@ -0,0 +1,99 @@ +import { createContext, useState, useEffect, use } from 'react'; +import axios from 'axios'; + +// 1. Initialize Context +const AuthContext = createContext(null); + +// 2. Create a Custom Provider Component +export function AuthProvider({ children }) { + const [user, setUser] = useState(null); + + useEffect(() => { + // Fetch user data from your backend API + const fetchUser = async () => { + // axios is directly used from Axios library to avoid interceptor + // added in services/api.js + try { + const response = await axios.get("/bff/api/security/me", { + timeout: 30000, // 30 seconds + headers: { 'Content-Type': 'application/json' }, + withCredentials: true + }); + if (response.data && 'username' in response.data) { + setUser(response.data); + } + } catch (error) { + console.log(error); + } + }; + fetchUser(); + }, []); + + const login = () => { + // Start single sign-on process (Using OAuth2, OpenID) + // Access /ui of API gateway. + // API gateway will redirect user to authorization server if the user is not logged in + // If logged in, API gateway will redirect browser to React app itself reloading the app. + window.location.href = "/bff/ui"; + } + + const logout = async () => { + // Logout from API gateway + try { + const response = await axios.post('/bff/logout', { + timeout: 30000, // 30 seconds + headers: { 'Content-Type': 'application/json' }, + withCredentials: true + }); + // Redirect browser to logout from authorization server. + window.location.href = response.headers.location; + // setUser(null) is not needed since browser is redirected. + } catch (error) { + console.log(error); + } + }; + + const isLoggedIn = () => { + if (user) { + return true; + } + + return false; + }; + + const isAdmin = () => { + return isInRole("ADMIN"); + } + + const isInRole = (role) => { + if (user && role && user.roles) { + return user.roles.includes(role); + } + + return false; + }; + + const isInRoles = (roles) => { + if (user && roles && user.roles) { + return roles.some(value => user.roles.includes(value)); + } + + return false; + } + + // Provide the state and the modifier function as a value object + return ( + + {children} + + ); +} + +// 3. Create a clean Custom Hook to consume this specific context +export function useAuth() { + const context = use(AuthContext); + if (!context) { + throw new Error('useAuth must be used within an AuthProvider'); + } + return context; +} -- cgit v1.2.3