A production-ready React application with OpenID Connect (OIDC) authentication integration
This project demonstrates a complete implementation of OIDC authentication in a modern React application using OpenID Connect protocol. Works with any OIDC-compliant provider including Keycloak, Auth0, Okta, Azure AD, and more. Built with Vite for optimal performance and developer experience.
- 🔐 OIDC Integration - Full OpenID Connect authentication flow with any provider
- 🌐 Multi-Provider Support - Works with Keycloak, Auth0, Okta, Azure AD, and more
- 🔄 Token Management - Automatic token refresh and silent renewal
- 🛡️ Protected Routes - Route guards with
OidcSecurewrapper - 📡 HTTP Interceptors - Axios interceptors for automatic token injection
- ⚡ Vite Build Tool - Lightning-fast HMR and optimized builds
- 🚀 React 19 - Latest React with compiler optimizations
- 🎯 React Router v7 - Modern routing with data APIs
For a complete guide and detailed explanation:
📝 Connecting OIDC in React Apps: The Practical Guide with Keycloak
- Node.js 18.x or higher
- npm or yarn package manager
- OIDC Provider - Any OpenID Connect compliant provider:
- Keycloak (used in this example)
- Auth0
- Okta
- Azure AD / Entra ID
- Google Identity
- Or any other OIDC provider
1. Clone the repository
git clone https://github.com/emronr/react-oidc-example.git
cd react-oidc-example2. Install dependencies
npm install3. Configure OIDC Provider
Edit src/configs/AuthConfig.js with your OIDC provider settings:
constoidcConfig={client_id: "your-client-id",authority: "https://your-oidc-provider/authority-url",// e.g., Keycloak: http://localhost:8080/realms/MyRealmredirect_uri: window.location.origin+"/authentication/callback",silent_redirect_uri:
window.location.origin+"/authentication/silent-callback",scope: "openid profile email offline_access",};4. Start development server
npm run devThe application will be available at http://localhost:5173
react-oidc-example/
├── src/
│ ├── configs/
│ │ └── AuthConfig.js # OIDC configuration
│ ├── hooks/
│ │ └── useAxiosInterceptors.js # Token injection hook
│ ├── pages/
│ │ ├── AuthTest.jsx # Authentication status demo
│ │ ├── BackendRequest.jsx # Protected API call example
│ │ └── Counter.jsx # Simple counter page
│ ├── routes/
│ │ └── RouteList.jsx # Application routes
│ ├── App.jsx # Main app component
│ ├── main.jsx # Application entry point
│ └── index.css # Global styles
├── public/ # Static assets
├── index.html # HTML template
├── vite.config.js # Vite configuration
├── eslint.config.js # ESLint configuration
└── package.json # Project dependencies
This example uses Keycloak as the OIDC provider, but you can use any OIDC-compliant provider. Below is the Keycloak setup guide:
1. Create a Realm
- Login to Keycloak Admin Console
- Create a new realm (e.g.,
MyRealm)
2. Create a Client
- Go to Clients → Create
- Configure the following:
| Setting | Value |
|---|---|
| Client ID | test-react-web |
| Client Protocol | openid-connect |
| Access Type | public |
| Standard Flow | Enabled |
| Valid Redirect URIs | http://localhost:5173/* |
| Web Origins | http://localhost:5173 |
| Admin URL | http://localhost:5173 |
3. Configure Scopes Ensure the following scopes are available:
openidprofileemailoffline_access(for refresh tokens)
Update src/configs/AuthConfig.js with your OIDC provider details:
For Keycloak:
constoidcConfig={client_id: "your-client-id",authority: "http://your-keycloak-server/realms/your-realm",redirect_uri: window.location.origin+"/authentication/callback",silent_redirect_uri:
window.location.origin+"/authentication/silent-callback",scope: "openid profile email offline_access",};For Auth0:
constoidcConfig={client_id: "your-auth0-client-id",authority: "https://your-domain.auth0.com",redirect_uri: window.location.origin+"/authentication/callback",silent_redirect_uri:
window.location.origin+"/authentication/silent-callback",scope: "openid profile email",};For Azure AD:
constoidcConfig={client_id: "your-azure-client-id",authority: "https://login.microsoftonline.com/your-tenant-id/v2.0",redirect_uri: window.location.origin+"/authentication/callback",silent_redirect_uri:
window.location.origin+"/authentication/silent-callback",scope: "openid profile email",};Use OidcSecure to protect components:
import{OidcSecure}from"@axa-fr/react-oidc";functionProtectedPage(){return(<OidcSecure><YourComponent/></OidcSecure>);}import{useOidcUser}from"@axa-fr/react-oidc";functionUserProfile(){const{ oidcUser }=useOidcUser();return(<div><h1>Welcome, {oidcUser.name}</h1><p>Email: {oidcUser.email}</p></div>);}import{useOidc}from"@axa-fr/react-oidc";functionTokenInfo(){const{ accessToken, refreshToken }=useOidc();console.log("Access Token:",accessToken);console.log("Refresh Token:",refreshToken);}The app uses the useAxiosInterceptors hook in App.jsx to automatically inject tokens into all Axios requests:
How it works:
// src/hooks/useAxiosInterceptors.jsimport{useOidcAccessToken}from"@axa-fr/react-oidc";exportfunctionuseAxiosInterceptors(){const{ accessToken }=useOidcAccessToken();useEffect(()=>{constrequestInterceptor=axios.interceptors.request.use((config)=>{if(accessToken){config.headers.Authorization=`Bearer ${accessToken}`;}returnconfig;});return()=>axios.interceptors.request.eject(requestInterceptor);},[accessToken]);}Usage in App.jsx:
import{useAxiosInterceptors}from"./hooks/useAxiosInterceptors";functionApp(){useAxiosInterceptors();// This enables automatic token injection// ...}Making API calls:
Once the hook is active, all Axios requests will automatically include the Bearer token:
importaxiosfrom"axios";asyncfunctionfetchProtectedData(){// Token is automatically added by the interceptorconstresponse=awaitaxios.get("http://localhost:8080/api/protected");returnresponse.data;}| Package | Version | Purpose |
|---|---|---|
| @axa-fr/react-oidc | ^7.26.3 | OIDC/OAuth2 client library |
| react | ^19.2.0 | UI framework |
| react-dom | ^19.2.0 | React DOM renderer |
| react-router-dom | ^7.13.0 | Client-side routing |
| axios | ^1.13.5 | HTTP client |
| Package | Purpose |
|---|---|
| vite | Build tool and dev server |
| @vitejs/plugin-react | React support for Vite |
| eslint | Code linting |
| babel-plugin-react-compiler | React compiler optimization |
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run ESLint
npm run lint- ✅ Tokens are stored securely by the OIDC library
- ✅ Automatic token refresh before expiration
- ✅ Silent token renewal for seamless UX
- ✅ Protected routes require valid authentication
- ✅ CORS properly configured for your OIDC provider
- ✅ PKCE (Proof Key for Code Exchange) support
Issue: Redirect loop
- Check that redirect URIs in your OIDC provider match exactly
- Verify Web Origins/Allowed Origins are configured in your provider
Issue: Token not attached to requests
- Ensure
useAxiosInterceptors()is called inApp.jsx - Verify Axios instance is properly configured
Issue: CORS errors
- Add your app URL to Allowed Origins in your OIDC provider settings
Issue: Authority URL not found
- Verify your authority URL is correct and accessible
- Check that your OIDC provider's discovery endpoint is available (
.well-known/openid-configuration)
This project is licensed under the MIT License.
Contributions are welcome! Feel free to:
- 🐛 Report bugs
- 💡 Suggest new features
- 🔧 Submit pull requests
Please ensure all PRs include appropriate tests and documentation.
Your Name
- 🌐 GitHub: @emronr
- ✍️ Medium: @emronr
- 💼 LinkedIn: @emre-onur
Made with ❤️ using React and OIDC
© 2026 - Present