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

如何配置NextAuth自定义凭证登录页面以实现身份认证?

问题分析与解决方案

你的核心问题是表单提交目标地址错误:credentials.callbackUrl是认证成功后的跳转目标,并非处理登录请求的API入口,直接提交到该地址自然会触发重定向而非认证操作。以下是两种正确的实现方式:


方案一:使用signIn函数处理表单提交(推荐)

这种方式更贴合NextAuth的设计逻辑,能便捷处理登录状态与错误信息:

import { getProviders, signIn } from "next-auth/react"

// 修正组件名拼写错误:Singin → SignIn
export default function SignIn({ providers:{credentials} }) {
  const handleSubmit = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const email = formData.get('email')
    const password = formData.get('password')

    // 调用NextAuth的signIn函数,指定credentials认证提供者
    const result = await signIn('credentials', {
      email,
      password,
      callbackUrl: credentials.callbackUrl // 认证成功后跳转地址
    })

    // 可在此处处理登录失败逻辑,比如展示错误提示
    if (result?.error) {
      console.error('登录失败:', result.error)
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Email address
        <input type="email" id="email" name="email" required />
      </label>
      <label>
        Password
        <input type="password" id="password" name="password" required />
      </label>
      <button type="submit">Sign in with Email</button>
    </form>
  )
}
  
export async function getServerSideProps(context) {
  const providers = await getProviders()
  return {
    props: { providers },
  }
}

方案二:原生表单提交(需指定正确API地址)

如果坚持使用原生表单提交,需明确提交到NextAuth的认证API,并添加必要的验证字段:

import { getProviders, getCsrfToken } from "next-auth/react"

export default function SignIn({ providers:{credentials}, csrfToken }) {
  return (
    <form method="post" action="/api/auth/signin/credentials">
      {/* 必须添加CSRF令牌,NextAuth会强制验证该字段 */}
      <input type="hidden" name="csrfToken" value={csrfToken} />
      {/* 指定认证成功后的跳转地址 */}
      <input type="hidden" name="callbackUrl" value={credentials.callbackUrl} />
      
      <label>
        Email address
        <input type="email" id="email" name="email" required />
      </label>
      <label>
        Password
        <input type="password" id="password" name="password" required />
      </label>
      <button type="submit">Sign in with Email</button>
    </form>
  )
}
  
export async function getServerSideProps(context) {
  const providers = await getProviders()
  const csrfToken = await getCsrfToken(context)
  return {
    props: { providers, csrfToken },
  }
}

额外修正:NextAuth配置的语法错误

你的authorize函数中有一处冗余括号,需修正:

// 原错误代码
const token = (await response).json() 
// 修正后
const token = await response.json()

同时,确保后端返回的token包含NextAuth识别的用户字段(如id、email),如果后端仅返回token字符串,需包装为对象返回:

if (response.ok && token) {
  return {
    id: '用户实际ID',
    email: credentials.email,
    accessToken: token
  }
}

内容的提问来源于stack exchange,提问作者Tlaloc-ES

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:15:49