生产环境Next.js集成NextAuth+Cognito回调遇502 Bad Gateway错误
问题:Next.js集成NextAuth+AWS Cognito生产环境Nginx 502错误
本地使用next dev或next start运行完全正常,但在Ubuntu搭配Nginx的生产服务器上,从Cognito内置登录页重定向至https://...../api/auth/callback/cognito?code=......&state=.....时,出现Nginx默认502错误页面。
已完成排查:
- 查阅过相关谷歌搜索结果、GitHub议题及StackOverflow问题
- 生产环境Next服务器与Nginx服务器的错误日志无异常
- 浏览器控制台日志无异常
- AWS Cognito中应用的
Callback URL(s)已设置为正确地址(https://......./api/auth/callback/cognito)
相关代码
middleware.ts
export { default } from "next-auth/middleware"; export const config = { matcher: ["/dashboard/:path*"] };
next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, swcMinify: true, compiler: { styledComponents: true, }, }; module.exports = nextConfig;
pages/api/auth/[...nextauth].ts
import CognitoProvider from "next-auth/providers/cognito"; import NextAuth, { NextAuthOptions, Session } from "next-auth"; import { AuthFlowType, CognitoIdentityProviderClient, InitiateAuthCommand, } from "@aws-sdk/client-cognito-identity-provider"; import { JWT } from "next-auth/jwt"; const COGNITO_AWS_REGION = process.env.COGNITO_AWS_REGION; const COGNITO_POOL_ID = process.env.COGNITO_POOL_ID; const COGNITO_CLIENT_ID = process.env.COGNITO_CLIENT_ID; const COGNITO_CLIENT_SECRET = process.env.COGNITO_CLIENT_SECRET; const NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET; const NEXTAUTH_URL = process.env.NEXTAUTH_URL; if (!COGNITO_AWS_REGION) throw new Error("REGION is not set"); if (!COGNITO_CLIENT_ID) throw new Error("COGNITO_CLIENT_ID is not set"); if (!COGNITO_POOL_ID) throw new Error("COGNITO_USER_POOL_ID is not set"); if (!COGNITO_CLIENT_SECRET) throw new Error("COGNITO_CLIENT_SECRET is not set"); if (!NEXTAUTH_SECRET) throw new Error("NEXTAUTH_SECRET is not set"); if (!NEXTAUTH_URL) throw new Error("NEXTAUTH_URL is not set"); const refreshCognitoAccessToken = async (token: JWT) => { const client = new CognitoIdentityProviderClient({ region: COGNITO_AWS_REGION, }); const command = new InitiateAuthCommand({ AuthFlow: AuthFlowType.REFRESH_TOKEN_AUTH, ClientId: COGNITO_CLIENT_ID, AuthParameters: { REFRESH_TOKEN: token.refreshToken as string, }, }); const response = await client.send(command); return response.AuthenticationResult; }; export const authOptions: NextAuthOptions = { secret: NEXTAUTH_SECRET, // @ts-expect-error -- this property is not documented properly site: NEXTAUTH_URL, providers: [ CognitoProvider({ clientId: COGNITO_CLIENT_ID!, issuer: `https://cognito-idp.${COGNITO_AWS_REGION}.amazonaws.com/${COGNITO_POOL_ID!}`, clientSecret: process.env.COGNITO_CLIENT_SECRET!, }), ], callbacks: { jwt: async ({ token, account, user }) => { // Initial sign in if (account && user) { return { // save token to session for authenticating to AWS accessToken: account.access_token, accessTokenExpires: account.expires_at ? account.expires_at * 1000 : 0, refreshToken: account.refresh_token, user, }; } // Return previous token if the access token has not expired yet if (Date.now() < (token as unknown as Session).accessTokenExpires) { return token; } // Access token has expired, try to update it const refreshedTokens = await refreshCognitoAccessToken(token); return { ...token, accessToken: refreshedTokens?.AccessToken, accessTokenExpires: refreshedTokens?.ExpiresIn ? Date.now() + refreshedTokens?.ExpiresIn * 1000 : 0, refreshToken: refreshedTokens?.RefreshToken ?? token.refreshToken, // Fall back to old refresh token }; }, session: async ({ session, token }) => { if (!session?.user || !token?.accessToken) { console.error("No accessToken found on token or session"); return session; } session.user = token.user as Session["user"]; session.accessToken = token.accessToken as string; session.error = token.error as string | undefined; return session; }, redirect: async ({ url, baseUrl }) => { // allows any url if (url.startsWith("/")) return `${baseUrl}${url}`; return url; }, }, }; export default NextAuth(authOptions);
排查与解决方案
1. Nginx反向代理配置问题
502错误核心原因通常是Nginx无法连接到上游Next.js服务器,检查以下配置点:
- 确认
proxy_pass指向的Next.js端口正确(默认3000,若自定义端口需对应) - 添加必要的请求头传递,避免Next.js无法识别真实请求地址:
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; - 增大
client_max_body_size,Cognito回调的URL参数可能较长,建议设置为client_max_body_size 20m;
完整Nginx配置示例:
server { listen 443 ssl; server_name your-domain.com; ssl_certificate /path/to/your-cert.pem; ssl_certificate_key /path/to/your-key.pem; location / { proxy_pass http://localhost: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; client_max_body_size 20m; } }
2. Next.js生产服务器稳定性与环境变量
- 使用
pm2或systemd托管Next.js进程,避免服务器意外退出导致Nginx无法连接 - 确认生产环境
NEXTAUTH_URL设置为完整HTTPS地址(如https://your-domain.com),与Cognito回调地址一致 - 检查
NEXTAUTH_SECRET是否与本地开发环境一致,密钥不一致会导致会话签名验证失败
3. NextAuth与Cognito配置优化
- 移除
authOptions中的site属性,NextAuth v4已废弃该属性,仅需通过NEXTAUTH_URL环境变量配置站点地址,旧属性可能导致回调地址生成异常 - 检查Cognito用户池App Client设置:
Allowed OAuth Flows需包含Authorization code grantAllowed OAuth Scopes需包含openid、email等必要权限
4. 网络与防火墙检查
- 确认服务器防火墙开放Next.js端口(默认3000),允许本地Nginx访问
- 若Cognito设置了IP白名单,需将生产服务器公网IP加入白名单,避免回调请求被拦截
内容的提问来源于stack exchange,提问作者Sheldonfrith
相关产品推荐
相关产品推荐

