Docker Compose部署Keycloak、Next.js与Spring Boot时的网络配置及令牌验证问题求助
Docker Compose部署Keycloak、Next.js与Spring Boot时的网络配置及令牌验证问题求助
我太懂你现在的头疼了——搭这三个服务时一会儿后端报issuer不匹配,一会儿前端跳错地址,折腾LLM也没搞定,完全摸不着头绪。咱们先把核心问题拆解清楚,再一步步把配置改对:
核心问题根源
- Issuer不匹配:Keycloak给前端发的JWT里,issuer是
http://localhost:8081/realms/polarix,但你后端用http://keycloak:8081/realms/polarix验证,两者不一致导致令牌验证失败。 - 内外网地址冲突:前端在浏览器里跑,必须用
localhost:8081访问Keycloak;但后端在Docker网络内,应该用服务名keycloak:8081访问Keycloak。你之前的Keycloak配置把KC_HOSTNAME设为localhost,导致它生成的所有地址都是localhost,后端验证时就会issuer不匹配。 - 前端构建与运行地址混乱:你用host网络构建前端,但运行时用桥接网络,可能导致前端请求地址硬编码错误。
修改后的完整Docker Compose配置
networks: polarix-network: driver: bridge services: dependency-builder: image: oven/bun:1-alpine working_dir: /app volumes: - .:/app command: bun install networks: - polarix-network postgres: image: postgres:13 container_name: postgres environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: password volumes: - postgres_data:/var/lib/postgresql/data - ./postgres-init:/docker-entrypoint-initdb.d ports: - "5432:5432" networks: - polarix-network healthcheck: test: ["CMD-SHELL", "pg_isready -U keycloak"] interval: 10s timeout: 5s retries: 5 start_period: 20s keycloak: image: quay.io/keycloak/keycloak:26.4.2 container_name: keycloak command: - start-dev - --import-realm environment: KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: password KC_HTTP_ENABLED: "true" KC_HTTP_PORT: 8081 # Docker内网用服务名,对外暴露用localhost KC_HOSTNAME: keycloak KC_HOSTNAME_URL: http://localhost:8081 KC_HOSTNAME_STRICT: "true" # 后端内部请求用服务名 KC_HOSTNAME_STRICT_BACKCHANNEL: "true" KC_HOSTNAME_BACKCHANNEL: http://keycloak:8081 volumes: - ./data/import:/opt/keycloak/data/import ports: - "8081:8081" networks: - polarix-network depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/localhost/8081'"] interval: 15s timeout: 10s retries: 5 start_period: 60s backend: build: ./backend container_name: backend environment: DB_URL: jdbc:postgresql://postgres:5432/polarix_db DB_USER: keycloak DB_PASSWORD: password # Issuer必须和JWT里的iss完全一致 KEYCLOAK_ISSUER_URI: http://localhost:8081/realms/polarix # 后端内网访问Keycloak拿JWKS用服务名 KEYCLOAK_JWKS_URI: http://keycloak:8081/realms/polarix/protocol/openid-connect/certs KEYCLOAK_SERVER_URL: http://keycloak:8081 ports: - "8080:8080" networks: - polarix-network depends_on: postgres: condition: service_healthy keycloak: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/v3/api-docs"] interval: 15s timeout: 5s retries: 5 frontend: build: context: . dockerfile: frontend/Dockerfile args: API_URL: http://localhost:8080 container_name: frontend environment: # Next.js静态构建时用环境变量传递地址 - NEXT_PUBLIC_API_URL=http://localhost:8080 - NEXT_PUBLIC_KEYCLOAK_URL=http://localhost:8081 ports: - "5173:5173" networks: - polarix-network depends_on: backend: condition: service_healthy volumes: postgres_data:
关键修改点解释
1. Keycloak配置(核心修复)
KC_HOSTNAME: keycloak:Docker内网的服务名,让后端能直接通过这个地址访问Keycloak,无需绕到主机。KC_HOSTNAME_URL: http://localhost:8081:告诉Keycloak对外(浏览器、前端)暴露的地址,确保生成的授权链接、JWT的issuer都是前端能访问的localhost。KC_HOSTNAME_STRICT_BACKCHANNEL: "true":强制后端的内部请求(比如验证令牌、获取JWKS)用keycloak:8081,避免地址混乱。
2. 后端配置修复
KEYCLOAK_ISSUER_URI必须和JWT里的iss字段完全一致(也就是http://localhost:8081/realms/polarix),这样令牌验证时issuer匹配。KEYCLOAK_JWKS_URI用Docker内网服务名,让后端高效访问Keycloak的证书接口。
3. 前端配置修复
- 用
NEXT_PUBLIC_*前缀的环境变量传递地址,Next.js会自动注入到前端代码中,避免构建时硬编码错误。 - 去掉了构建时的
network: host,没必要且容易引发网络问题,直接用默认构建网络即可。
额外注意事项
- 删掉旧容器和卷:启动前先执行
docker-compose down -v,清除旧的缓存配置。 - Keycloak客户端配置:在Keycloak后台把前端地址
http://localhost:5173加到Valid Redirect URIs和Web Origins里,避免CORS或回调错误。 - Spring Boot后端补充配置:确保你的application.yml里的JWT验证配置和docker-compose一致:
spring: security: oauth2: resourceserver: jwt: issuer-uri: ${KEYCLOAK_ISSUER_URI} jwk-set-uri: ${KEYCLOAK_JWKS_URI} - 去掉/etc/hosts的多余配置:你之前加的127.0.0.1
完全没必要,反而可能触发浏览器的安全限制导致crypto函数错误。
验证步骤
- 启动所有服务:
docker-compose up --build - 访问Keycloak后台:
http://localhost:8081/admin,确认能正常登录。 - 访问前端:
http://localhost:5173,点击登录验证是否跳转到Keycloak页面,登录后能否正常调用后端API。 - 查看后端日志:确认没有issuer不匹配的错误,令牌验证通过。
这样应该就能解决你遇到的所有网络和令牌验证问题了,如果还有小问题,比如CORS或前端跳转错误,直接检查Keycloak的客户端配置和前端的环境变量就行~




