A simple demo and useful playground for integrating Keycloak with React frontend and Spring backend, using standard OpenID Connect protocol.
Main technical stack involved (with exact depencency versions):
- Keycloak: v25.0.1
- React: v18.3.1
- react-oidc-context: v3.1.0 (which interact with Keycloak to auth user and get OIDC tokens)
- oidc-client-ts: v3.0.1
- react-router: v6.24.0
- react-query: v5.49.2
- react-toastify: v10.0.5
- react18-json-view: v0.2.8
- tailwindcss: v3.4.4
- daisyui: v4.12.10
- heroicons: v2.1.4
- typescript: v5.4.5
- vite: v5.2.10
- Spring Boot: v3.3.1
- spring-boot-starter-oauth2-resource-server: bundled (which interact with Keycloak to validate OIDC tokens and get user info)
- spring-boot-starter-webflux: bundled
- kotlin: v2.0.0
- gradle: v8.7
Link: https://keycloak-react-spring-demo.pages.dev
- After redirecting to Keycloak login page, enter username
test
and passwordtest
. - You can also access the Keycloak admin console, with username
admin
and passwordadmin
.
Showing what you'll get (that is, a AuthContextProps
object) in frontend after login:
Sending request (with or without token) to backend, and get response with decoded JWT:
Open a terminal in current directory, and run the following command:
docker compose up --build
Keycloak server will be running at http://localhost:8080.
Open another terminal in current directory, and run the following command:
cd backend
./gradlew bootRun
Backend Spring app will be running at http://localhost:8000.
Open a third terminal in current directory, and run the following command:
cd frontend
npm install
npm run dev
Now, visit frontend URL: http://localhost:3000, you will be redirected to Keycloak login page.
In this demo, I will use Google Cloud Run and Cloudflare Pages as examples.
First, setup your Google Cloud project ID and region:
export GCLOUD_PROJECT_ID=<YOUR_PROJECT_ID>
export GCLOUD_REGION=<YOUR_REGION>
Build Docker image and push to Google Container Registry:
cd keycloak
docker build . -t mykeycloak
docker tag mykeycloak gcr.io/${GCLOUD_PROJECT_ID}/keycloak:latest
docker push gcr.io/${GCLOUD_PROJECT_ID}/keycloak:latest
Note: if you're using Mac with M-series chip, you should build Docker image using following cross-compile command:
docker buildx build --platform=linux/amd64 . -t mykeycloak
Then, deploy to Google Cloud Run using following command:
gcloud run deploy keycloak \
--image=gcr.io/${GCLOUD_PROJECT_ID}/keycloak:latest \
--platform=managed \
--region=${GCLOUD_REGION} \
--allow-unauthenticated \
--port=8080 \
--memory=2Gi \
--cpu=4 \
--min-instances=0 \
--max-instances=1 \
--set-env-vars KC_HOSTNAME=keycloak-lta4azdwga-uc.a.run.app
Note: KC_HOSTNAME should be set to the domain of your deployed instance, which may only be able to obtain after deployment:
gcloud run services describe keycloak --platform=managed --region=${GCLOUD_REGION}
You can first ignore KC_HOSTNAME, and then update it after deployment.
Instead of building Docker image yourself, we can leverage gcloud CLI's source-to-image
cd backend
gcloud run deploy spring-backend \
--source . \
--platform=managed \
--region=${GCLOUD_REGION} \
--allow-unauthenticated \
--memory=512Mi \
--cpu=2 \
--min-instances=0 \
--max-instances=1 \
--set-env-vars KEYCLOAK_REALM_URL=https://keycloak-lta4azdwga-uc.a.run.app/realms/myrealm,CORS_ALLOWED_ORIGINS=https://keycloak-react-spring-demo.pages.dev
You can deploy a Cloudflare Pages project using CLI, direct upload, or Git integration, see docs.
In this demo, I used Git integration to integration this GitHub repo with Cloudflare Pages. After configured, you can deploy the front app by running the following command:
./deploy.sh frontend
This demo is inspired by the following projects: