Skip to content

AleMoz97/doodle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Doodle Free (Keycloak Auth, NestJS, React)

Stack:

  • Frontend: React + Vite + Tailwind + MUI
  • Backend: NestJS + Prisma
  • DB app: PostgreSQL
  • Auth: Keycloak (OIDC Authorization Code + PKCE)

Local URLs:

  • Frontend: http://localhost:5173
  • Backend API: http://localhost:3000
  • Keycloak: http://localhost:8080

1) Start infrastructure (Docker Compose)

From backend/:

cd backend
docker compose up -d

Services started:

  • postgres (single DB server for app + Keycloak) on localhost:5432
  • keycloak on localhost:8080
  • mailhog (legacy/dev utility)

2) Configure Keycloak (manual)

Open http://localhost:8080. Admin credentials (from compose):

  • username: admin
  • password: admin

Create realm

  • Realm name: doodle

Disable self-registration

  • Realm Settings -> Login
  • Set User registration to OFF

Create frontend client (SPA)

  • Clients -> Create client
  • Client ID: doodle-frontend
  • Client type: OpenID Connect
  • Access type: Public
  • Standard flow: Enabled
  • Direct access grants: Disabled
  • Root URL: http://localhost:5173
  • Valid redirect URIs: http://localhost:5173/*
  • Web origins: http://localhost:5173

Create backend API client

Recommended: Confidential (resource server use case).

  • Clients -> Create client
  • Client ID: doodle-api
  • Client type: OpenID Connect
  • Access type: Confidential
  • Standard flow: disabled (not required for API)

Add audience mapper (important)

To include API audience in access tokens issued to frontend:

  • Open doodle-frontend client
  • Client scopes / Mappers -> Add mapper
  • Mapper type: Audience
  • Included Client Audience: doodle-api
  • Add to access token: ON

This ensures aud contains doodle-api.

Create users (manual provisioning)

  • Users -> Create new user
  • Set username/email
  • Enable user
  • Credentials -> Set password
  • Mark password as Temporary
  • Required Actions should include UPDATE_PASSWORD (add it if missing)

At first login, Keycloak will force password change before returning to the app.

3) Backend setup

backend/.env should contain:

PORT=3000
DATABASE_URL=postgresql://myuser:mypassword@localhost:5432/mydatabase
KEYCLOAK_ISSUER=http://localhost:8080/realms/doodle
KEYCLOAK_JWKS_URI=http://localhost:8080/realms/doodle/protocol/openid-connect/certs
KEYCLOAK_API_AUDIENCE=doodle-api
KEYCLOAK_ALLOW_AZP_FALLBACK=true
FRONTEND_ORIGIN=http://localhost:5173

Run Prisma + API:

cd backend
npm install
npx prisma generate
npx prisma migrate dev
npm run start:dev

4) Frontend setup

frontend/.env should contain:

VITE_API_BASE_URL=http://localhost:3000
VITE_KEYCLOAK_URL=http://localhost:8080
VITE_KEYCLOAK_REALM=doodle
VITE_KEYCLOAK_CLIENT_ID=doodle-frontend

Run frontend:

cd frontend
npm install
npm run dev

5) What changed

  • Custom auth endpoints removed (/auth/login, /auth/signup-request, /auth/verify, /auth/set-password, /auth/refresh, /auth/logout).
  • Backend now validates Keycloak JWTs using JWKS (/protocol/openid-connect/certs), issuer, and audience.
  • Guard sets req.user as:
    • sub
    • email
    • preferred_username
    • dbUserId
  • On authenticated calls, user is upserted in app DB by keycloakSub + email.
  • Prisma User model now uses Keycloak identity fields only.

6) First-login password change test

  1. Admin creates user in Keycloak with temporary password.
  2. User clicks Login in frontend.
  3. Keycloak redirects to password update screen.
  4. After update, redirect back to app.
  5. API calls succeed with Bearer token.

7) Troubleshooting

Invalid audience

Symptom: 401 Invalid token audience.

Fix:

  • Verify audience mapper on doodle-frontend includes doodle-api in access token.
  • Confirm backend .env has KEYCLOAK_API_AUDIENCE=doodle-api.

Invalid issuer

Symptom: 401 Invalid token issuer.

Fix:

  • Ensure backend uses KEYCLOAK_ISSUER=http://localhost:8080/realms/doodle.
  • Confirm token iss claim matches exactly.

CORS errors

Fix:

  • Backend FRONTEND_ORIGIN must be http://localhost:5173.
  • Keycloak client web origin must include http://localhost:5173.

Redirect URI mismatch

Fix:

  • In Keycloak doodle-frontend client, set valid redirect URIs to http://localhost:5173/*.

Missing email claim

Symptom: 401 Token missing email claim.

Fix:

  • Ensure frontend login uses openid profile email scope.
  • Ensure Keycloak client scopes include email.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages