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

NextAuth v4登录失败重定向异常问题求助

NextAuth v4 登录错误时无法跳转到指定页面问题解决

我在全栈JS课程的最终项目中使用NextAuth v4.18.8(课程采用v3版本)开发登录页面,输入正确密码时可正常跳转至http://127.0.0.1:3000/user/dashboard;但输入错误密码时,未按预期跳转到/auth/signin?i=1,反而被重定向至http://127.0.0.1:3000/api/auth/error?error=Request%20failed%20with%20status%20code%20401,控制台显示POST http://localhost:3000/api/auth/callback/credentials? 401 (Unauthorized)错误。

排查发现:输入错误密码时,后端signin控制器返回res.status(401).json({ success: false, message: "invalid" }),此时axios请求会直接抛出异常,导致前端[...nextauth].js中CredentialsProvider的authorize函数内,判断用户不存在时抛出'/auth/signin?i=1'的代码无法执行。

相关代码

前端:登录页面

const handleFormSubmit = async values => {
  signIn('credentials', {
   email: values.email,
   password: values.password,
   callbackUrl: 'http://127.0.0.1:3000/user/dashboard'
  })
}

前端:[...nextauth].js

export const authOptions = {
  providers: [
    CredentialsProvider({
        name: 'credentials',
        async authorize(credentials, req) {
            const res = await axios.post('http://127.0.0.1:3000/api/auth/signin', credentials)

            const user = res.data

            if (user) {
                return user
            } else {
                throw '/auth/signin?i=1'
            }
          }
    })
  ],

  session: {
    jwt: true
  }, 

  jwt: {
    secret: process.env.JWT_TOKEN
  },

  adapter: MongooseAdapter(process.env.MONGODB_URI)
}
export default NextAuth(authOptions)

后端:signin.js控制器

const authSignin = {

    post: async (req, res) => {
        const {
            name,
            email,
            password,
          } = req.body

          await dbConnect()
          
          const user = await UsersModel.findOne({ email })

          if (!user) {
            return res.status(401).json({ success: false, message: "invalid" })
          }

          const passIsCorrect = await compare(password, user.password)

          if (passIsCorrect) {
            return res.status(200).json({
              _id: user._id,
              name: user.name,
              email: user.email
            })
          }
        
          
          return res.status(401).json({ success: false, message: "invalid" })
 
        }
}

export { authSignin }

后端:signin.js路由(使用Next Connect)

import nextConnect from 'next-connect'

import { authSignin } from '../../../src/controllers/auth/signin'
 
const route = nextConnect()

route.post(authSignin.post)

export default route

解决方法

问题核心是axios遇到401状态码会直接抛出异常,导致authorize函数的错误分支代码无法执行。提供两种解决方案:

方案1:捕获axios异常并手动抛出跳转路径

修改[...nextauth].js中的authorize函数,添加异常捕获逻辑:

async authorize(credentials, req) {
  try {
    const res = await axios.post('http://127.0.0.1:3000/api/auth/signin', credentials)
    const user = res.data
    if (user) {
      return user
    } else {
      throw '/auth/signin?i=1'
    }
  } catch (error) {
    // 捕获401异常,抛出指定跳转路径
    if (error.response?.status === 401) {
      throw '/auth/signin?i=1'
    }
    // 其他异常重新抛出,保留原有错误逻辑
    throw error
  }
}

方案2:调整后端接口返回状态码

修改后端signin控制器,将验证失败时的401状态码改为200,通过success字段标识结果:

// 替换原401返回逻辑
if (!user) {
  return res.status(200).json({ success: false, message: "invalid" })
}

// ...

return res.status(200).json({ success: false, message: "invalid" })

同时修改前端authorize函数的判断逻辑:

async authorize(credentials, req) {
  const res = await axios.post('http://127.0.0.1:3000/api/auth/signin', credentials)
  const user = res.data

  if (user.success) {
    return { _id: user._id, name: user.name, email: user.email }
  } else {
    throw '/auth/signin?i=1'
  }
}

两种方案任选其一即可,方案1更符合HTTP状态码语义规范,推荐使用。

内容的提问来源于stack exchange,提问作者João Textor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:55:14