You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境下NextJs集成Keycloak认证遇ECONNREFUSED错误求助

Docker环境下NextJS 14集成Keycloak 25.0.1的连接问题解决方法

问题根源

容器内部网络与宿主机网络相互隔离:

  • NextJS容器内的localhost指向容器自身,而非宿主机,因此用http://localhost:8080访问Keycloak会被拒绝
  • 直接用容器名keycloak:8080作为issuer,会导致浏览器重定向到这个仅容器内部可访问的地址,宿主机浏览器无法打开

解决方案

需要区分**服务器端(NextAuth API路由)和客户端(浏览器)**的Keycloak访问地址,同时配置Keycloak客户端的合法跳转规则。

1. 修正Keycloak客户端配置

登录Keycloak管理控制台(http://localhost:8080/admin),找到nextjs realm下的nextjs_client客户端:

  • Valid Redirect URIs:添加http://localhost:3000/api/auth/callback/keycloak
  • Web Origins:添加http://localhost:3000
  • 保存配置

2. 修改环境变量

在.env文件中分别定义服务器端和客户端使用的Keycloak地址:

KEYCLOAK_CLIENT_ID=nextjs_client
KEYCLOAK_CLIENT_SECRET=abcdefghijklmnopqrs
# 服务器端(NextJS容器内部访问Keycloak用)
KEYCLOAK_ISSUER_SERVER=http://keycloak:8080/realms/nextjs
# 客户端(浏览器访问Keycloak用)
KEYCLOAK_ISSUER_CLIENT=http://localhost:8080/realms/nextjs
NEXT_AUTH_SECRET=your_nextauth_secret_here # 可通过`openssl rand -hex 32`生成随机值

3. 更新NextAuth配置

修改pages/api/auth/[...nextauth].ts,分别指定服务器端和客户端的Keycloak接口地址:

import NextAuth from "next-auth"
import KeycloakProvider from "next-auth/providers/keycloak"

export const authOptions = {
  debug: true,
  secret: process.env.NEXT_AUTH_SECRET,
  providers: [
    KeycloakProvider({
      clientId: process.env.KEYCLOAK_CLIENT_ID || "",
      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET || "",
      // 服务器端调用用容器内部地址
      issuer: process.env.KEYCLOAK_ISSUER_SERVER,
      // 客户端重定向用宿主机地址
      authorization: {
        url: `${process.env.KEYCLOAK_ISSUER_CLIENT}/protocol/openid-connect/auth`,
      },
      // 服务器端token/userinfo/jwks接口调用用容器内部地址
      token: {
        url: `${process.env.KEYCLOAK_ISSUER_SERVER}/protocol/openid-connect/token`,
      },
      userinfo: {
        url: `${process.env.KEYCLOAK_ISSUER_SERVER}/protocol/openid-connect/userinfo`,
      },
      jwks_endpoint: `${process.env.KEYCLOAK_ISSUER_SERVER}/protocol/openid-connect/certs`,
      // 可选:自定义用户信息映射,如需开启取消注释
      // profile(profile) {
      //   return {
      //     id: profile.sub,
      //     name: profile.name ?? profile.preferred_username,
      //     email: profile.email,
      //   }
      // },
    }),
  ],
}
export default NextAuth(authOptions)

4. 优化Docker启动顺序(可选)

添加健康检查确保MySQL完全启动后再启动Keycloak,避免因依赖服务未就绪导致的启动失败,修改docker-compose.yml:

version: '3.8'

services:
  nextjs:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - mysql
      - keycloak
    volumes:
      - .:/app
    command: sh -c "npm run dev"

  mysql:
    image: mysql:8.0
    ports:
      - '3306:3306'
    command: ["mysqld", "--init-file=/docker-entrypoint-initdb.d/init.sql"]
    volumes:
      - mysql-data:/var/lib/mysql
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 5s
      timeout: 5s
      retries: 5
    environment:
      MYSQL_ROOT_PASSWORD: your_mysql_root_password # 需设置MySQL根密码

  keycloak:
    image: quay.io/keycloak/keycloak:25.0.1 # 固定版本,避免自动更新导致兼容性问题
    depends_on:
      mysql:
        condition: service_healthy
    ports:
      - 8080:8080
    volumes:
      - keycloak-data:/opt/keycloak/data
      - ./keycloak-config:/opt/keycloak/data/import
    command: ["start-dev", "--import-realm"]
    environment:
      KEYCLOAK_ADMIN: admin # 设置Keycloak管理员账号
      KEYCLOAK_ADMIN_PASSWORD: admin # 设置管理员密码

volumes:
  mysql-data:
  keycloak-data:

验证步骤

  1. 重启所有容器:docker-compose down && docker-compose up -d
  2. 访问NextJS应用(http://localhost:3000),点击登录按钮
  3. 检查是否正常跳转到Keycloak登录页面,登录后是否能成功返回NextJS应用

内容的提问来源于stack exchange,提问作者user23455176

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:20:10