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
相关产品推荐
相关产品推荐

