FastAPI Keycloak Integration with React Frontend
Table of Contents
- Introduction
- Features
- Project Structure
- Prerequisites
- Installation
- Configuration
- Usage
- Authentication Flow
- Development
- Contributing
- License
Introduction
This project provides a full-stack authentication solution using FastAPI as the backend, React (with TypeScript and Tailwind CSS) as the frontend, and Keycloak as the identity provider. Authentication is handled securely using HTTP-only cookies to protect tokens from XSS attacks.
Features
- FastAPI Backend: A modern, fast web framework for building APIs with Python 3.12+
- React Frontend: TypeScript-based React application with Tailwind CSS for styling
- Keycloak Integration: Enterprise-grade identity management with OAuth2/OpenID Connect
- Secure Cookie-Based Auth: HTTP-only cookies protect access tokens from XSS attacks
- Dockerized Setup: Full Docker Compose setup including Keycloak, backend, and frontend
- Poetry for Python Dependencies: Simplified Python dependency management
Project Structure
.
├── .env.example # Environment variables template
├── docker-compose.yaml # Production Docker Compose
├── docker-compose.dev.yaml # Development Docker Compose
├── README.md
├── backend/
│ ├── Dockerfile
│ ├── pyproject.toml
│ ├── poetry.lock
│ └── src/
│ ├── __init__.py
│ ├── config.py # Keycloak & cookie settings
│ ├── controller.py # Request handlers
│ ├── main.py # FastAPI app with CORS
│ ├── models.py # Pydantic models
│ └── service.py # Keycloak auth service
└── frontend/
├── Dockerfile
├── nginx.conf # Production nginx config
├── package.json
├── tsconfig.json
├── tailwind.config.js
├── vite.config.ts
└── src/
├── App.tsx
├── main.tsx
├── index.css
├── components/ # Reusable UI components
├── context/ # React Context (AuthContext)
├── hooks/ # Custom hooks (useAuth)
├── pages/ # Page components
├── services/ # API service layer
└── types/ # TypeScript types
Prerequisites
- Docker and Docker Compose
- Node.js 20+ (for local frontend development)
- Python 3.12+ (for local backend development)
- Git
Installation
-
Clone the Repository
git clone https://github.com/your-repo/fastapi-keycloak.git cd fastapi-keycloak -
Copy Environment Variables File
cp .env.example .env -
Configure Environment Variables
Open the
.envfile and update the following variables:# Keycloak Configuration KEYCLOAK_SERVER_URL=http://localhost:8081/ KEYCLOAK_REALM=your-realm KEYCLOAK_CLIENT_ID=your-client-id KEYCLOAK_CLIENT_SECRET=your-client-secret # Frontend URL (for CORS and redirects) FRONTEND_URL=http://localhost:3000 # Cookie Configuration COOKIE_SECURE=false # Set to true in production with HTTPS COOKIE_SAMESITE=lax COOKIE_MAX_AGE=3600
Configuration
Setting Up Keycloak
-
Start the Services
docker-compose up keycloak -d -
Access the Keycloak Admin Console
Open
http://localhost:8081/and login with:- Username:
admin - Password:
admin
- Username:
-
Create a New Realm
- Click "Create Realm"
- Name it (e.g.,
my-app) - Click "Create"
-
Create a New Client
- Go to Clients → Create client
- Client ID: e.g.,
my-app-client - Client Protocol:
openid-connect - Click Next
- Enable "Client authentication" (confidential)
- Enable "Standard flow" and "Direct access grants"
- Click Next
- Valid redirect URIs:
http://localhost:8080/* - Web origins:
http://localhost:3000 - Click Save
-
Get Client Secret
- Go to Credentials tab
- Copy the "Client secret"
- Update your
.envfile
-
Create a Test User
- Go to Users → Add user
- Username:
testuser - Email:
test@example.com - Click Create
- Go to Credentials tab → Set password
- Disable "Temporary"
Usage
Running with Docker (Production)
# Start all services
docker-compose up --build
# Services will be available at:
# - Frontend: http://localhost:3000
# - Backend API: http://localhost:8080
# - Keycloak: http://localhost:8081
Running with Docker (Development)
For development with hot-reload on the backend:
# Start Keycloak and Backend only
docker-compose -f docker-compose.dev.yaml up --build
# In another terminal, start the frontend dev server
cd frontend
npm install
npm run dev
Authentication Flow
- User clicks "Login" → Frontend redirects to
/api/login - Backend redirects to Keycloak → User authenticates with Keycloak
- Keycloak redirects back → Backend receives authorization code at
/api/callback - Backend exchanges code for token → Sets HTTP-only cookie with access token
- Backend redirects to frontend → User lands on
/dashboard - Frontend calls
/api/auth/me→ Backend validates cookie and returns user info
API Endpoints
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api |
GET | No | Welcome message and docs link |
/api/login |
GET | No | Initiates OAuth2 login flow |
/api/callback |
GET | No | OAuth2 callback (sets cookie) |
/api/auth/me |
GET | Cookie | Get current user info |
/api/auth/logout |
POST | Cookie | Clear auth cookie |
/api/protected |
GET | Bearer | Protected endpoint (token in header) |
/docs |
GET | No | Swagger API documentation |
Development
Backend Development
cd backend
poetry install
poetry run uvicorn src.main:app --reload --port 8080
Frontend Development
cd frontend
npm install
npm run dev
The frontend dev server runs on http://localhost:3000 and proxies /api requests to the backend.
Environment Variables
See .env.example for all available configuration options:
- Keycloak settings: Server URL, realm, client ID/secret
- Frontend URL: For CORS and OAuth redirects
- Cookie settings: Security options for the auth cookie
Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
License
This project is licensed under the MIT License.