Next.js+Better Auth登录成功后服务端组件重定向循环问题
我们的应用基于Next.js App Router构建(独立输出模式),使用Better Auth做身份验证、Prisma作为ORM,部署在Docker容器并通过Nginx反向代理。登录流程出现以下异常:
/api/auth/sign-in/username返回200,会话和用户JSON正常返回- 浏览器成功存储
__Secure-better-auth.session_token安全Cookie - 数据库Session表已创建对应会话记录
- 客户端请求
/api/auth/get-session返回200,会话状态活跃 - 核心问题:页面重定向到
/时,服务端组件调用auth.api.getSession返回null,触发重定向回/sign-in形成循环
应用在Vercel上运行正常,错误凭证登录返回401证明数据库连接正常。
可能的原因及解决方案
1. 配置Next.js信任反向代理
Next.js默认不信任代理请求,会导致无法正确识别HTTPS环境及传递的Cookie。在next.config.js中添加信任配置:
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', // 信任请求的Host头 trustHost: true, experimental: { // 信任反向代理传递的X-Forwarded-*头 trustProxy: true, }, } module.exports = nextConfig
同时可设置环境变量NEXT_TRUST_HOST=true强化配置。
2. 修复Nginx反向代理的请求头转发
确保Nginx将完整的请求头(包括Cookie和HTTPS协议标识)转发给Next.js服务,修改Nginx配置:
location / { proxy_pass http://your-nextjs-container-name:3000; # 传递原始Host头 proxy_set_header Host $host; # 传递真实客户端IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 关键:告诉Next.js请求实际使用的协议(HTTPS) proxy_set_header X-Forwarded-Proto $scheme; # 确保Cookie头被完整传递,不被Nginx修改 proxy_pass_header Set-Cookie; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
重点是X-Forwarded-Proto头——__Secure-前缀的Cookie仅在HTTPS环境下会被服务端读取,若Next.js服务未收到该头,会认为请求是HTTP,忽略Secure Cookie。
3. 调整Better Auth的Session Cookie配置
在Better Auth初始化时,开启信任代理并适配生产环境的Cookie设置:
import { BetterAuth } from "better-auth"; import { prismaAdapter } from "@better-auth/prisma-adapter"; import prisma from "./prisma"; export const auth = BetterAuth({ database: prismaAdapter(prisma), session: { cookie: { // 生产环境启用Secure Cookie secure: process.env.NODE_ENV === "production", sameSite: "lax", // 设置与前端一致的域名,确保Cookie跨子域可用(若有需要) domain: process.env.NEXT_PUBLIC_APP_DOMAIN, path: "/", }, // 让Better Auth信任反向代理传递的X-Forwarded-Proto头 trustProxy: true, }, // 其他身份验证配置... });
trustProxy: true会让Better Auth优先使用X-Forwarded-Proto判断请求协议,确保Secure Cookie被正确读取。
4. 检查Docker Compose网络与域名配置
- 确保Next.js容器和Nginx容器处于同一Docker网络,避免网络隔离导致请求头传递异常
- 确认
NEXT_PUBLIC_APP_DOMAIN环境变量设置为前端实际访问的域名(如example.com),而非容器内部的主机名
5. 排查Proxy.ts中间件
若项目中使用了自定义Proxy中间件,确保中间件未拦截或修改Cookie、X-Forwarded-*等关键请求头,避免会话信息丢失。
验证步骤
- 重启Nginx和Next.js容器,使配置生效
- 登录后查看Next.js服务的请求日志,确认
X-Forwarded-Proto: https和Cookie头存在 - 在服务端组件中添加日志打印
auth.api.getSession()的返回值,验证是否能正常获取会话
内容的提问来源于stack exchange,提问作者Stykgwar
相关产品推荐
相关产品推荐

