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

NextJS自定义Credentials登录报错后跳转默认表单问题求助

问题排查与解决

核心问题:pages 配置位置错误

你把 pages 属性放在了 CredentialsProvider 内部,但根据NextAuth的规则,pages 是属于 authOptions 的顶层配置项,而非某个Provider的子属性。这个错误会导致NextAuth无法识别你的自定义登录页面配置,登录失败时仍会跳转到默认页面。

修正后的 [...nextauth].js 代码

export const authOptions = {
  // 将pages移到authOptions顶层,与providers同级
  pages: {
    signIn: '/account/login',
  },
  providers: [
    CredentialsProvider({
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Juan@mail.uy" },
        password: { label: "Password", type: "password", placeholder: "********" },
      },
      async authorize(credentials, req) {
        const { email, password } = credentials;

        try {
          const user = await User.findOne({ email });
          if (!user) {
            return null;
          }

          const isPasswordValid = await bcrypt.compare(password, user.password);
          if (!isPasswordValid) {
            return null;
          }

          return user;
        } catch (error) {
          return null;
        }
      }

    })
  ],
}

额外优化:前端捕获错误不跳转

如果希望登录失败时留在自定义登录页面显示错误,而非依赖NextAuth的重定向,可以在调用 signIn 时添加 redirect: false 参数:

const handleSubmit = async e => {
    e.preventDefault();
    setLoading(true);

    const formData = new FormData(e.target);
    const options = {
        email: formData.get('email'),
        password: formData.get('password'),
        redirect: false, // 禁止自动重定向
        callbackUrl: redirect || '/' // 确保回调地址存在
    };

    try {
        const result = await signIn('credentials', options);
        // 登录失败时,result会包含error字段
        if (result?.error) {
            setError('邮箱或密码错误');
        } else {
            // 登录成功后手动跳转
            window.location.href = options.callbackUrl;
        }
    } catch (e) {
        setError(e.message);
    } finally {
        setLoading(false);
    }
};

补充:自定义登录页面获取错误参数

如果保留默认重定向逻辑,你可以在自定义登录页面通过路由参数获取错误信息,比如在 login.js 中:

import { useRouter } from 'next/router';

export default function LoginPage() {
  const router = useRouter();
  const { error } = router.query;

  return (
    <div>
      {error === 'CredentialsSignin' && <p className="error">邮箱或密码错误</p>}
      {/* 登录表单 */}
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:23:08