# FastAPI Keycloak Integration with React Frontend ## Table of Contents - [Introduction](#introduction) - [Features](#features) - [Project Structure](#project-structure) - [Prerequisites](#prerequisites) - [Installation](#installation) - [Configuration](#configuration) - [Usage](#usage) - [Authentication Flow](#authentication-flow) - [Development](#development) - [Contributing](#contributing) - [License](#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](https://www.docker.com/get-started) and [Docker Compose](https://docs.docker.com/compose/install/) - [Node.js 20+](https://nodejs.org/) (for local frontend development) - [Python 3.12+](https://www.python.org/downloads/) (for local backend development) - [Git](https://git-scm.com/) ## Installation 1. **Clone the Repository** ```bash git clone https://github.com/your-repo/fastapi-keycloak.git cd fastapi-keycloak ``` 2. **Copy Environment Variables File** ```bash cp .env.example .env ``` 3. **Configure Environment Variables** Open the `.env` file and update the following variables: ```env # 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 1. **Start the Services** ```bash docker-compose up keycloak -d ``` 2. **Access the Keycloak Admin Console** Open `http://localhost:8081/` and login with: - Username: `admin` - Password: `admin` 3. **Create a New Realm** - Click "Create Realm" - Name it (e.g., `my-app`) - Click "Create" 4. **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 5. **Get Client Secret** - Go to Credentials tab - Copy the "Client secret" - Update your `.env` file 6. **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) ```bash # 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: ```bash # 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 1. **User clicks "Login"** → Frontend redirects to `/api/login` 2. **Backend redirects to Keycloak** → User authenticates with Keycloak 3. **Keycloak redirects back** → Backend receives authorization code at `/api/callback` 4. **Backend exchanges code for token** → Sets HTTP-only cookie with access token 5. **Backend redirects to frontend** → User lands on `/dashboard` 6. **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 ```bash cd backend poetry install poetry run uvicorn src.main:app --reload --port 8080 ``` ### Frontend Development ```bash 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.