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

NextAuth子域名环境下getSession返回null问题求助

跨子域名共享NextAuth会话解决方案

针对主平台(http://localhost)认证后,子域名应用(http://sub.localhost)调用getSession()返回null的问题,按以下步骤排查修复:

1. 核心配置一致性检查

  • 强制共用NEXTAUTH_SECRET:子应用.env.local中的NEXTAUTH_SECRET必须和主平台完全一致。NextAuth依赖这个密钥签名会话Token,不一致会导致子应用无法解析主平台生成的Cookie。
  • 共用同一数据库:确认主、子应用的DATABASE_URL指向同一个数据库实例。PrismaAdapter会将会话数据存储到数据库,子应用需要从同一份数据源读取会话信息。

2. 统一Cookie域名规则

主平台Cookie配置修正

你的getDomainWithoutSubdomain函数处理localhost时会返回localhost,最终Cookie domain设为.localhost,但部分浏览器对localhost子域名的Cookie存在兼容性限制。直接调整Cookie配置逻辑:

// 主平台[...nextauth].js
const hostName = process.env.NODE_ENV === 'development' 
  ? 'localhost' 
  : getDomainWithoutSubdomain(process.env.NEXTAUTH_URL);

const options = {
  // ...其他配置
  cookies: {
    sessionToken: {
      name: process.env.NODE_ENV === 'production' ? `__Secure-next-auth.session-token` : 'next-auth.session-token',
      options: {
        httpOnly: true,
        sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    },
    // 必须同步配置其他NextAuth Cookie的domain规则
    callbackUrl: {
      name: process.env.NODE_ENV === 'production' ? `__Secure-next-auth.callback-url` : 'next-auth.callback-url',
      options: {
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    },
    csrfToken: {
      name: process.env.NODE_ENV === 'production' ? `__Host-next-auth.csrf-token` : 'next-auth.csrf-token',
      options: {
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    }
  }
}

子应用必须同步Cookie配置

子应用的[...nextauth].js需要完全复用主平台的Cookie规则,确保能识别主平台设置的跨子域名Cookie:

// 子应用[...nextauth].js
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import prisma from '../../../lib/prisma';

const hostName = process.env.NODE_ENV === 'development' 
  ? 'localhost' 
  : getDomainWithoutSubdomain(process.env.NEXTAUTH_URL);

const options = {
  secret: process.env.NEXTAUTH_SECRET, // 必须和主平台一致
  adapter: PrismaAdapter(prisma), // 必须配置,从共用数据库读取会话
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  cookies: {
    // 完全复制主平台的Cookie配置
    sessionToken: {
      name: process.env.NODE_ENV === 'production' ? `__Secure-next-auth.session-token` : 'next-auth.session-token',
      options: {
        httpOnly: true,
        sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    },
    callbackUrl: {
      name: process.env.NODE_ENV === 'production' ? `__Secure-next-auth.callback-url` : 'next-auth.callback-url',
      options: {
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    },
    csrfToken: {
      name: process.env.NODE_ENV === 'production' ? `__Host-next-auth.csrf-token` : 'next-auth.csrf-token',
      options: {
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        domain: process.env.NODE_ENV === 'development' ? '.localhost' : `.${hostName}`
      }
    }
  }
}

export default (req, res) => NextAuth(req, res, options);

3. 修正NextAuth URL配置

  • 主平台.env.local:NEXTAUTH_URL=http://localhost(移除末尾斜杠),NEXTAUTH_URL_INTERNAL=http://主平台容器名:3000(替换为实际Docker服务名)。
  • 子应用.env.local:NEXTAUTH_URL=http://sub.localhost(移除末尾斜杠),NEXTAUTH_URL_INTERNAL=http://子应用容器名:3000(不能和主平台共用同一个内部URL)。

4. Nginx反向代理配置检查

确保Nginx转发请求时正确传递Host头,否则NextAuth无法识别当前域名导致Cookie设置错误:

server {
  listen 80;
  server_name localhost;

  location / {
    proxy_pass http://主平台容器名:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

server {
  listen 80;
  server_name sub.localhost;

  location / {
    proxy_pass http://子应用容器名:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

5. 开发环境兼容性处理

如果Chrome等浏览器仍无法识别localhost子域名的Cookie,修改本地hosts文件(/etc/hosts或C:\Windows\System32\drivers\etc\hosts),添加自定义域名映射:

127.0.0.1       local.test
127.0.0.1       sub.local.test

然后将主、子应用的NEXTAUTH_URL分别改为http://local.test和http://sub.local.test,Cookie domain设为.local.test,即可正常测试跨子域名会话共享。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:05:21