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

跨子域Next.js应用用auth.js认证遇UntrustedHost问题求助

跨子域Next.js应用的Auth.js认证问题解决指南

问题背景

在Next.js多区域架构中使用Auth.js时,https://console.my-app.com下的多个应用均重写到部署了自定义认证中间件的主应用;另有独立部署在https://panel.my-app.com的应用,不做重写。原本通过同一Auth.js配置实现了跨子域共享登录、认证有效,但现在panel.my-app.com认证失效,服务器报错:

panel:start: [auth][error] UntrustedHost: Host must be trusted. URL was: https://panel.my-app.com/api/auth/session. Read more at https://errors.authjs.dev#untrustedhost
panel:start:     at /app/apps/panel/.next/server/middleware.js:389:48416
panel:start:     at ac (/app/apps/panel/.next/server/middleware.js:389:51116)
panel:start:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

补充信息

  • 两个应用均为Next.js应用
  • 共用相同的自定义认证中间件:
function useAuthMiddleware(
  middleware: CustomMiddleware,
): CustomMiddleware | NextMiddlewareResult {
  return auth((request) => {
    const response = NextResponse.next()
    if (isUnprotectedRoute(request.nextUrl.pathname)) return NextResponse.next()
    if (!request.auth)
      return NextResponse.redirect("https://console.my-app.com/login")
    return middleware(request, undefined, response)
  })
}
  • 共用相同的auth.config.ts配置:
export const Local = Credentials({
  credentials: {
    email: {},
    password: {},
  },
  authorize: async (credentials) => {
    const client = new FetchClient()
    try {
      const authBody = await client.post({
        url: `https://api.my-app.com/auth-token`,
        data: {
          email: credentials.email,
          password: credentials.password,
        },
        config: {
          headers: {
            'Content-Type': 'application/json',
          },
        },
      })
      return authBody
    } catch (error) {
      console.error(error)
      return null
    }
  },
})

// Define how we want the session token to be stored in our browser
const cookies: NextAuthConfig['cookies'] = {
  sessionToken: {
    name: `session-token`,
    options: {
      httpOnly: true,
      sameSite: 'lax',
      path: '/',
      secure: useSecureCookies,
      domain: "console.my-app.com",
    },
  },
}

export default {
  providers: [Local, Google],
  secret: AUTH_SECRET,
  pages: {
    signIn: '/login',
    error: '/500',
  },
  useSecureCookies,
  cookies,
} satisfies NextAuthConfig
  • 主应用环境变量:AUTH_URL=https://console.my-app.com
  • console.my-app.com为多区域架构,多个应用重写到主应用;panel.my-app.com为独立子域应用

疑问解答

1. 能否使用Auth.js为多个不同子域的Next.js应用实现跨域用户认证?

可以实现,但需要满足两个核心条件:

  • 会话Cookie的domain设置为父域(如.my-app.com),确保所有子域能共享该Cookie
  • 所有子域都被加入Auth.js的信任主机列表,避免触发UntrustedHost错误

2. 若需将域名加入信任列表,该如何操作?

有两种可靠配置方式:

方式一:在Auth.js配置中添加trustHost选项

在auth.config.ts中指定信任的主机:

export default {
  // ...其他原有配置
  // 生产环境建议指定具体域名数组,避免安全风险
  trustHost: ["console.my-app.com", "panel.my-app.com"],
  // 开发环境可临时设为true,方便调试
  // trustHost: true
}

方式二:通过环境变量AUTH_TRUST_HOST配置

在两个应用的环境变量中添加:

# 生产环境指定具体域名,多个用逗号分隔
AUTH_TRUST_HOST=console.my-app.com,panel.my-app.com
# 开发环境可设为true
# AUTH_TRUST_HOST=true

3. 原本正常的认证为何突然失效?

大概率是以下原因之一:

  • 信任主机配置变更:误修改了trustHost配置或对应环境变量,导致panel.my-app.com被移除出信任列表
  • Cookie域名限制:当前Cookie的domain设为console.my-app.com,panel.my-app.com无法读取该Cookie;原本正常可能是之前配置的是父域.my-app.com,之后被修改
  • Auth.js版本更新:部分版本对信任主机的校验逻辑做了调整,升级后未同步配置
  • 环境变量覆盖:panel.my-app.com的环境变量中新增了AUTH_URL或AUTH_TRUST_HOST,覆盖了全局统一配置

跨子域认证最佳实践

  1. 统一Cookie域名:将Cookie的domain改为父域,确保所有子域能共享会话Cookie:
const cookies: NextAuthConfig['cookies'] = {
  sessionToken: {
    name: `session-token`,
    options: {
      httpOnly: true,
      sameSite: 'lax',
      path: '/',
      secure: useSecureCookies,
      domain: ".my-app.com", // 改为父域,注意开头的点
    },
  },
}
  1. 明确配置信任主机:生产环境务必指定具体信任域名,禁止使用trustHost: true,避免安全风险
  2. 统一核心环境变量:两个应用共享AUTH_SECRET、AUTH_TRUST_HOST等变量,避免配置不一致
  3. 优化中间件跳转逻辑:确保登录完成后能跳回原应用,修改中间件的跳转代码:
if (!request.auth) {
  const callbackUrl = encodeURIComponent(request.nextUrl.href)
  return NextResponse.redirect(`https://console.my-app.com/login?callbackUrl=${callbackUrl}`)
}
  1. 验证Cookie共享:在浏览器开发者工具的Application标签下,检查两个子域是否能读取到同一个session-token Cookie

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:24:54