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

Next.js + Auth.js v5 Credentials登录遇CallbackRouteError求助

Next.js + Auth.js v5 凭据登录错误问题解决

问题描述

使用Next.js和Auth.js v5实现凭据登录认证,输入错误登录凭据时,预期返回{error: "Invalid credentials"},但实际触发CallbackRouteError,未找到有效解决方案。

错误信息

[auth][error] CallbackRouteError: Read more at https://errors.authjs.dev#callbackrouteerror
[auth][cause]: Error
at Module.callback (webpack-internal:///(action-browser)/./node_modules/@auth/core/lib/actions/callback/index.js:226:23)
...
[auth][details]: {"provider": "credentials"}

相关代码

登录Action代码

"use server"

import * as z from 'zod';
import { AuthError } from "next-auth";

import { signIn } from "@/auth";
import { LoginSchema } from '@/schemas';
import { DEFAULT_LOGIN_REDIRECT } from "@/routes";

export const login = async (values: z.infer<typeof LoginSchema>) => {
    const validatedFields = LoginSchema.safeParse(values);

    if(!validatedFields.success){
        return {error: "Invalid fields"}
    }

    const { email, password } = validatedFields.data;

    try {
        await signIn("credentials", {
            email,
            password,
            redirectTo: DEFAULT_LOGIN_REDIRECT,
        })
    } catch (error) {
        if(error instanceof AuthError){
            switch (error.type) {
                case "CredentialsSignin":
                    return {error: "Invalid credentials"}
                case "CallbackRouteError":
                    return {error: "An error occurred with the callback route"}
                default:
                    return {error: "An error occurred"}
            }
        }

        throw error;
    }
};

NextAuth配置代码

import bcrypt from "bcryptjs";
import type { NextAuthConfig } from "next-auth"
import Credentials from "next-auth/providers/credentials"

import { LoginSchema } from "@/schemas"
import { getUserByEmail } from "@/data/users";

export default {
    providers: [
        Credentials({
            async authorize(credentials: any ) {
                const validateFields = LoginSchema.safeParse(credentials)

                if(validateFields.success) {
                    const { email, password } = validateFields.data


                    const user = await getUserByEmail(email);
                    if (!user || !user.password) return null;

                    const passwordsMatch = await bcrypt.compare(
                        password,
                        user.password
                    );

                    if(passwordsMatch) return user;
                }

                return null;
            }
        })
    ]
} satisfies NextAuthConfig

解决方案

1. 修改NextAuth配置:主动抛出凭据错误

Auth.js v5中,authorize函数返回null时会默认触发CallbackRouteError,而非预期的CredentialsSignin错误。需要在验证失败时主动抛出CredentialsSignin错误:

import bcrypt from "bcryptjs";
import type { NextAuthConfig } from "next-auth"
import Credentials from "next-auth/providers/credentials"
import { CredentialsSignin } from "@auth/core/errors"; // 导入错误类

import { LoginSchema } from "@/schemas"
import { getUserByEmail } from "@/data/users";

export default {
    providers: [
        Credentials({
            async authorize(credentials: any ) {
                const validateFields = LoginSchema.safeParse(credentials)

                if(!validateFields.success) {
                    throw new CredentialsSignin("Invalid fields");
                }

                const { email, password } = validateFields.data;

                const user = await getUserByEmail(email);
                if (!user || !user.password) {
                    throw new CredentialsSignin("Invalid credentials");
                }

                const passwordsMatch = await bcrypt.compare(password, user.password);
                if(!passwordsMatch) {
                    throw new CredentialsSignin("Invalid credentials");
                }

                return user;
            }
        })
    ]
} satisfies NextAuthConfig

2. 修改登录Action:禁用自动跳转并处理返回结果

默认signIn会自动跳转,验证失败时的跳转逻辑会触发CallbackRouteError。设置redirect: false禁用自动跳转,直接获取验证结果:

"use server"

import * as z from 'zod';
import { signIn } from "@/auth";
import { LoginSchema } from '@/schemas';
import { DEFAULT_LOGIN_REDIRECT } from "@/routes";

export const login = async (values: z.infer<typeof LoginSchema>) => {
    const validatedFields = LoginSchema.safeParse(values);

    if(!validatedFields.success){
        return {error: "Invalid fields"}
    }

    const { email, password } = validatedFields.data;

    const result = await signIn("credentials", {
        email,
        password,
        redirect: false, // 禁用自动跳转
    });

    if (result?.error) {
        return { error: result.error === "CredentialsSignin" ? "Invalid credentials" : result.error };
    }

    // 验证成功后手动跳转
    return { success: true, redirectTo: DEFAULT_LOGIN_REDIRECT };
};

3. 可选:配置自定义错误页面(若需跳转)

如果仍需使用自动跳转,需在NextAuth配置中指定登录错误页面,避免触发路由错误:

export default {
    providers: [/* ... */],
    pages: {
        signIn: "/login", // 指定登录页路径
        error: "/login", // 指定错误跳转页面
    },
} satisfies NextAuthConfig

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:15:25