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

NextJS 15 + AuthV5在Bolt.new用npm登录时出现请求域错误

NextJS 15 + Auth.js V5 凭证登录报错:headers was called outside a request scope

问题描述

在NextJS 15与Auth.js V5项目中,使用凭证登录时触发以下错误:

Error: headers was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

已完成的测试场景:

  • 本地环境用npm/bun运行:完全正常
  • Vercel平台用npm/bun部署运行:完全正常
  • 仅在Bolt.new平台用npm运行时出现该错误

相关简化代码

/auth/signin/page.ts

import { AuthForm } from "@/components/auth/auth-form";
import { login } from "@/app/actions/auth-actions";

export default function SignInPage() {
  return <AuthForm type="signin" action={login} />;
}

auth-action.ts

"use server";

import { signIn, signOut } from "@/auth";

export const login = async (values: z.infer<typeof SignInSchema>) => {
  // ... 表单验证逻辑
  try {
    await signIn("credentials", {
      email,
      password,
      redirectTo: DEFAULT_LOGIN_REDIRECT(existingUser.defaultWorkspaceId!),
    });
    return { success: "Logged in!" };
  } catch (error) {
    // ... 错误处理逻辑
  };
}

表单客户端组件

"use client";
// ... 导入依赖

export function AuthForm({ type, action }: AuthFormProps) {
  // ... Formik/React Hook Form 初始化逻辑
  function onSubmit(values: z.infer<typeof schema>) {
    setError("");
    setSuccess("");
    startTransition(() => {
      action(values).then((data) => {
        setError(data?.error);
        setSuccess(data?.success);
      });
    });
  }
  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        {/* ... 输入框、提交按钮等表单元素 */}
      </form>
    </Form>
  );
}

auth.ts

export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  pages: {
    signIn: "/auth/signin",
    error: "/auth/error",
  },
  callbacks: {
    async signIn({ user, account }) {
      if (account?.provider !== "credentials") return true;
      const existingUser = await getUserById(user.id!);
      if (!existingUser || !existingUser?.emailVerified) return false;
      return true;
    },
    // ... 其他回调逻辑
});

解决方案

结合场景差异(仅Bolt.new报错),核心原因是平台对NextJS请求上下文的处理或静态优化策略不同,以下是针对性修复步骤:

1. 强制登录页面动态渲染

Bolt.new可能默认对页面做了静态预渲染,导致页面在无请求上下文的环境下初始化,进而引发Server Action的上下文错误。在登录页面添加动态渲染指令:

// /auth/signin/page.ts
import { AuthForm } from "@/components/auth/auth-form";
import { login } from "@/app/actions/auth-actions";

// 强制页面每次请求都动态渲染,确保请求上下文存在
export const dynamic = "force-dynamic";

export default function SignInPage() {
  return <AuthForm type="signin" action={login} />;
}

2. 改用NextJS原生formAction调用Server Action

手动在startTransition中调用Server Action可能存在上下文传递问题,改用原生表单绑定方式:

// 表单客户端组件修改
export function AuthForm({ type, action }: AuthFormProps) {
  // ... 表单初始化逻辑
  return (
    <Form {...form}>
      <form action={action} onSubmit={form.handleSubmit((values) => {
        setError("");
        setSuccess("");
      })}>
        {/* ... 表单元素 */}
        <button type="submit">登录</button>
      </form>
    </Form>
  );
}

3. 检查redirectTo生成逻辑

确保DEFAULT_LOGIN_REDIRECT函数没有调用依赖请求上下文的API(如headers()、auth()),如果有这类逻辑,需移到Server Action的请求上下文内执行。

4. 验证Bolt.new的Node.js版本

确认Bolt.new使用的Node.js版本与本地/Vercel一致(NextJS 15推荐Node.js 18+),版本差异可能导致上下文处理不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:42:22