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

在AWS Lambda中使用serverless-http时NextAuth.js signIn()方法失效

NextAuth.js 在 AWS CDK 部署的 Lambda + HttpApi 环境下登录无响应问题排查与解决

问题场景

通过 AWS CDK 部署 NextJS + NextAuth.js 应用,使用 serverless-http 适配 Lambda 与 NextJS 的绑定。本地开发(yarn dev)或本地构建启动(yarn build && yarn start)时登录功能正常,但部署到 AWS 后:

  • 点击「Sign In」跳转至 /api/auth/signin?callbackUrl=%2F,点击「Sign in with credentials」后页面仅刷新,无登录会话生成也不跳转首页
  • 测试 Cognito Provider 时,点击登录出现「Unexpected token」错误,signIn(...) 函数尝试将登录页解析为 JSON

客户端与服务端均无报错,推测核心问题为域名、请求头或 Cookie 配置不匹配 Serverless 环境特性。


解决方案

1. 启用 NextAuth 的 Host 信任机制

NextAuth 默认仅信任 NEXTAUTH_URL 配置的域名,但 HttpApi 转发请求时的 Host 头可能为 API Gateway 内部域名,导致 NextAuth 无法正确识别回调地址。

修改 [...nextauth].ts,添加 trustHost 配置:

export const authOptions: NextAuthOptions = {
  // 原有配置...
  trustHost: true, // 允许 NextAuth 信任请求的 Host 头
  // 其他配置...
}

2. 修正 Serverless HTTP 的请求头传递

serverless-http 默认可能未正确传递真实 Host 头,导致 NextJS 无法识别自定义域名。修改 server.ts:

import { NextConfig } from "next";
import NextServer from "next/dist/server/next-server";
import serverless from "serverless-http";
// @ts-ignore
import { config } from "./.next/required-server-files.json";

// 从环境变量获取真实域名,避免硬编码 localhost
const hostname = process.env.NEXTAUTH_URL?.split('://')[1] || "localhost";

const nextServer = new NextServer({
    hostname,
    port: 3000,
    dir: __dirname,
    dev: false,
    conf: {
        ...(config as NextConfig),
    },
});

// 配置 serverless-http 传递真实 Host 头
export const handler = serverless(nextServer.getRequestHandler(), {
  request: (req) => {
    req.headers.host = req.headers['x-forwarded-host'] || req.headers.host;
  },
});

3. 配置 HttpApi 的 CORS 与凭证支持

HttpApi 默认集成未开启凭证(Cookie)支持,导致浏览器无法保存 NextAuth 的会话 Cookie。修改 CDK 的 HttpApi 配置:

var httpApi = new HttpApi(this, "http-api", new HttpApiProps
{
    DisableExecuteApiEndpoint = true,
    DefaultIntegration = new HttpLambdaIntegration("nextjs-route", function),
    DefaultDomainMapping = new DomainMappingOptions
    {
        DomainName = "myDomainName.com"
    },
    // 添加 CORS 预飞行配置
    CorsPreflight = new CorsPreflightOptions
    {
        AllowHeaders = new[] { "*" },
        AllowMethods = new[] { CorsHttpMethod.GET, CorsHttpMethod.POST, CorsHttpMethod.PUT, CorsHttpMethod.DELETE, CorsHttpMethod.OPTIONS },
        AllowOrigins = new[] { "https://myDomainName.com" }, // 明确指定自定义域名
        AllowCredentials = true // 允许携带 Cookie 等凭证
    }
});

同时在 NextAuth 中显式配置 Cookie 域名:

export const authOptions: NextAuthOptions = {
  // 原有配置...
  cookies: {
    sessionToken: {
      name: `__Secure-next-auth.session-token`,
      options: {
        domain: ".myDomainName.com", // 带前缀点适配子域名(若有)
        path: "/",
        secure: true,
        httpOnly: true,
        sameSite: 'lax'
      }
    }
  },
  // 其他配置...
}

4. 优化构建脚本依赖完整性

原构建脚本仅手动复制 serverless-http 依赖,可能遗漏 NextAuth 运行所需的其他包。修改构建脚本,直接复用 NextJS standalone 打包的完整依赖:

#!/bin/bash

BUILD_FOLDER=.dist

yarn build
rm -rf $BUILD_FOLDER
# 复制 standalone 目录下所有内容(含完整 node_modules)
cp -r .next/standalone/* $BUILD_FOLDER/
# 复制静态资源与公共文件
cp -r .next/static $BUILD_FOLDER/.next/
cp -r public $BUILD_FOLDER/
# 复制配置文件与编译后的 server.ts
cp next.config.js $BUILD_FOLDER/
tsc server.ts --outDir $BUILD_FOLDER --esModuleInterop true

5. 升级 Lambda 运行时

确保 Lambda 使用 NODEJS_18_X 或更高版本(NextJS 13+ 推荐),避免版本兼容问题。同时确认 NEXTAUTH_SECRET 为有效随机字符串(可通过 openssl rand -hex 32 生成)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:05:23