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
相关产品推荐
相关产品推荐

