NextAuth:如何不重定向返回自定义错误
实现NextAuth用户名密码登录的自定义错误返回
1. 在authorize方法中抛出自定义错误
在[...nextauth].js/ts的CredentialsProvider配置里,直接抛出包含自定义信息的Error对象,替代默认的重定向或空返回:
import NextAuth from "next-auth" import CredentialsProvider from "next-auth/providers/credentials" export default NextAuth({ providers: [ CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" } }, async authorize(credentials) { // 模拟数据库查询逻辑 const user = await fetchUserByEmail(credentials.email) if (!user) { throw new Error("无效的邮箱地址") } if (user.isBanned) { throw new Error("账户已封禁") } const isPasswordValid = await verifyPassword(credentials.password, user.passwordHash) if (!isPasswordValid) { throw new Error("无效密码") } return user } }) ], session: { strategy: "jwt" }, callbacks: { async jwt({ token, user }) { if (user) token.user = user return token }, async session({ session, token }) { session.user = token.user return session } }, pages: { signIn: "/login" }, debug: process.env.NODE_ENV === "development" })
2. 客户端调用signIn时捕获自定义错误
客户端调用signIn时,必须设置redirect: false,这样会返回包含错误信息的对象而非直接重定向,然后通过result.error获取自定义消息:
import { signIn } from "next-auth/react" const handleLogin = async (email, password) => { try { const result = await signIn("credentials", { email, password, redirect: false // 关键:禁用重定向,获取返回结果 }) if (result.ok) { // 登录成功逻辑,比如跳转首页 window.location.href = "/" } else { // 拿到自定义错误消息,展示给用户 console.error("登录失败:", result.error) setError(result.error) } } catch (error) { // 处理网络等意外错误 console.error("登录请求出错:", error) setError("登录请求失败,请稍后重试") } }
3. 进阶:返回自定义错误码
如果需要返回结构化的错误码(如INVALID_EMAIL),可以给Error对象添加code属性,再通过自定义错误处理逻辑返回给客户端:
修改authorize方法
async authorize(credentials) { const user = await fetchUserByEmail(credentials.email) if (!user) { const error = new Error("无效的邮箱地址") error.code = "INVALID_EMAIL" throw error } if (user.isBanned) { const error = new Error("账户已封禁") error.code = "ACCOUNT_BANNED" throw error } const isPasswordValid = await verifyPassword(credentials.password, user.passwordHash) if (!isPasswordValid) { const error = new Error("无效密码") error.code = "INVALID_PASSWORD" throw error } return user }
添加自定义错误处理
在[...nextauth].js/ts中添加error回调,将错误码和消息以JSON格式返回:
export default NextAuth({ // ...其他配置 async error({ error, req, res }) { if (error.code) { res.status(401).json({ error: error.message, code: error.code }) return } res.status(500).json({ error: "服务器内部错误" }) } })
客户端捕获错误码
const handleLogin = async (email, password) => { try { const result = await signIn("credentials", { email, password, redirect: false }) if (result.ok) { window.location.href = "/" } else { // 同时拿到错误码和消息 console.error("错误码:", result.code, "错误消息:", result.error) setError(result.error) } } catch (error) { console.error("登录请求出错:", error) setError("登录请求失败,请稍后重试") } }
内容的提问来源于stack exchange,提问作者WPalombini
相关产品推荐
相关产品推荐

