在 NextAuth.js 中使用带有自定义后端的凭证提供程序!

2025-06-10

在 NextAuth.js 中使用带有自定义后端的凭证提供程序!

您好!如果您要为 next.js 应用添加身份验证功能,NextAuth 是一个不错的选择。它的优势显而易见,因为它支持 Google、Github、Facebook、Apple、Slack、Twitter 等众多服务提供商,能够在几分钟内帮您设置好身份验证!

然而,有时出于各种原因,您可能需要使用自定义后端,并使用电子邮件/密码登录。这时,您需要使用与 API 服务器关联的凭证提供程序。我遇到过类似的情况,但找不到详细的说明和示例,所以我花了一段时间才弄清楚所有细节(尤其是处理自定义后端的错误以及如何在自定义登录页面上处理它们)。如果您也遇到同样的情况,希望以上内容对您有所帮助!

首先,我们需要为应用设置 Next-Auth。设置过程很简单,具体说明可在此处查看。

现在我们需要设置pages/api/[..nextauth].js如下内容



import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import axios from 'axios'

const providers = [
  Providers.Credentials({
    name: 'Credentials',
    authorize: async (credentials) => {
      const user = await axios.post('https://myapi.com/login',
        {
          user: {
            password: credentials.password,
            email: credentials.email
          }
        },
        {
          headers: {
            accept: '*/*',
            'Content-Type': 'application/json'
          }
        })

      if (user) {
        return user
      } else {
        return null
      }
    }
  })
]

const callbacks = {
  // Getting the JWT token from API response
  async jwt(token, user) {
    if (user) {
      token.accessToken = user.token
    }

    return token
  },

  async session(session, token) {
    session.accessToken = token.accessToken
    return session
  }
}

const options = {
  providers,
  callbacks
}

export default (req, res) => NextAuth(req, res, options)



Enter fullscreen mode Exit fullscreen mode

在我的例子中,您的自定义登录页面pages/login.js将有一个表单提交处理程序,它将使用 nextauth 的 signIn 函数来登录用户



import { signIn } from 'next-auth/client'

const handleLogin = () => {
    signIn('credentials',
      {
        email,
        password,
        // The page where you want to redirect to after a 
        // successful login
        callbackUrl: `${window.location.origin}/account_page` 
      }
    )
  }



Enter fullscreen mode Exit fullscreen mode

此时,如果您输入了正确的凭据并且您的 API 端点按您希望的方式工作,那么您应该能够正常登录。

但是如果出现任何问题,例如服务器宕机、凭据无效等,您将被重定向到默认错误页面(如下图所示)。

NextAuth 错误

我想要的是将其重定向到我的自定义登录页面,并向用户更详细地解释情况。所以我们需要pages/api/[..nextauth].js稍微调整一下



import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import axios from 'axios'

const providers = [
  Providers.Credentials({
    name: 'Credentials',
    authorize: async (credentials) => {
      try {
        const user = await axios.post('https://myapi.com/login',
        {
          user: {
            password: credentials.password,
            email: credentials.email
          }
        },
        {
          headers: {
            accept: '*/*',
            'Content-Type': 'application/json'
          }
        })

        if (user) {
          return {status: 'success', data: user}
        } 
      } catch (e) {
        const errorMessage = e.response.data.message
        // Redirecting to the login page with error message          in the URL
        throw new Error(errorMessage + '&email=' + credentials.email)
      }

    }
  })
]

const callbacks = {
  async jwt(token, user) {
    if (user) {
      token.accessToken = user.data.token
    }

    return token
  },

  async session(session, token) {
    session.accessToken = token.accessToken
    return session
  }
}

const options = {
  providers,
  callbacks,
  pages: {
    error: '/login' // Changing the error redirect page to our custom login page
  }
}

export default (req, res) => NextAuth(req, res, options)



Enter fullscreen mode Exit fullscreen mode

我们还将更新我们的登录页面pages/login.js以查找 URL 更改和任何错误消息



import { useRouter } from 'next/router'

export default function Login () {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [loginError, setLoginError] = useState('')
  const router = useRouter()

  useEffect(() => {
    // Getting the error details from URL
    if (router.query.error) {
      setLoginError(router.query.error) // Shown below the input field in my example
      setEmail(router.query.email) // To prefill the email after redirect
    }
  }, [router])
}



Enter fullscreen mode Exit fullscreen mode

通过此设置,我们可以在自定义登录页面上以我们喜欢的格式显示错误消息。例如,我将从服务器收到的错误消息显示如下:

用户友好的错误消息

附言:我没有在代码片段中添加 HTML 部分,因为它本身就一目了然。但如果你需要,请在评论区告诉我,我会添加的 :)

您可以在此处找到代码

希望本文能够帮助您完成自定义身份验证!

向@iainCollins@balazsorban和所有NextAuth.js贡献者致敬,感谢他们的出色工作!

鏂囩珷鏉ユ簮锛�https://dev.to/twisha/using-credentials-provider-with-a-custom-backend-in-nextauth-js-43k4
PREV
VSCODE 许可证问题——你应该担心
NEXT
你需要了解的 5 大机器学习算法