NextAuth Credentials登录成功后无跳转无日志问题排查求助
问题描述
在Next.js应用中使用NextAuth Credentials提供器实现身份验证,用户输入正确凭据后系统无任何反应。预期验证成功后自动跳转到仪表板,但实际既无跳转,控制台、网络面板也没有可排查问题的日志输出。
相关代码
/[...nextauth].js
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import { PrismaAdapter } from "@auth/prisma-adapter"; import prisma from '../../../utils/db'; import { compare } from "bcrypt"; export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email", placeholder: "you@company.com" }, password: { label: "Password", type: "password" } }, async authorize(credentials) { let existingUser = null; try { if (!credentials?.email || !credentials?.password) { throw new Error("Missing credentials"); } existingUser = await prisma.user.findUnique({ where: { email: credentials?.email }, }); if (!existingUser) { throw new Error("User not found"); } const passwordMatch = await compare(credentials?.password, existingUser.password); if (!passwordMatch) { throw new Error("Invalid password"); } return { id: `${existingUser.id}`, email: existingUser.email }; } catch (error) { console.error("Authentication error:", error.message); return null; } } }), ], adapter: PrismaAdapter(prisma), session: { strategy: 'jwt', }, secret: process.env.NEXTAUTH_SECRET, pages: { signIn: '/login', signOut: '/login', error: '/404', }, debug: true, }; export default NextAuth(authOptions);
/signIn.js
//SignIn import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; import { signIn } from 'next-auth/react'; import { useSession } from 'next-auth/react'; const SignIn = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [errors, setErrors] = useState(''); const { data: session } = useSession(); const router = useRouter(); const handleOnSubmit = async (e) => { e.preventDefault(); setErrors(''); try { console.log("Attempting to sign in with:", email, password); const signInData = await signIn('Credentials', { email, password, redirect: false, }); console.log("signInData:", signInData); if (signInData?.ok) { console.log("Sign-in successful!"); router.push('/dashboard'); } else { console.error('Authentication failed:', signInData.error); setErrors(`Authentication failed: ${signInData.error}`); } } catch (error) { console.error('Authentication error:', error.message); setErrors(`Authentication error: ${error.message}`); } }; const openModal = (e) => { e.preventDefault(); setOpen(true); }; return ( <div className=""> <div className=""> {errors && <p style={{color: 'red'}}>{errors}</p>} <form onSubmit={handleOnSubmit} className=""> <label htmlFor="email" > Email address </label> <input type="email" label="Email address" value={email} onChange={(e) => setEmail(e.target.value)} required /> <label htmlFor="password"> Password </label> <input type="password" label="Password" value={password} onChange={(e) => setPassword(e.target.value)} required /> <button type="submit">登录</button> </form> </div> </div> ); };
utils/db.js(prisma实例文件)
import { PrismaClient } from "@prisma/client"; import { withAccelerate } from "@prisma/extension-accelerate"; let prisma: PrismaClient; const globalForPrisma = global as any; if (process.env.NODE_ENV === "production") { prisma = new PrismaClient(); } else { if (!globalForPrisma.prisma) { globalForPrisma.prisma = new PrismaClient().$extends(withAccelerate()); } prisma = globalForPrisma.prisma; } export default prisma;
关键问题与修复步骤
1. 表单缺少提交按钮
原signIn.js中的表单没有提交按钮,用户无法触发登录提交事件,这是无响应的直接原因。添加<button type="submit">登录</button>后才能触发handleOnSubmit函数。
2. signIn调用的redirect参数设置
默认redirect: true时,signIn会直接跳转页面,后续的控制台日志和逻辑判断都不会执行。调试阶段设置redirect: false,可以获取返回结果并在控制台查看,验证成功后手动跳转。
3. 逻辑判断错误
原代码使用位运算符&替代逻辑与&&,且错误判断session状态(redirect: false时session不会立即更新),修正为直接判断signInData?.ok即可。
4. 错误状态未正确管理
原setErrors函数仅返回字符串,未更新组件状态。新增useState('')定义errors状态,用于在页面显示错误信息,方便用户排查问题。
5. NextAuth配置冗余
原pages配置中的dashboard: '/dashboard'不是NextAuth的内置页面选项,NextAuth仅支持signIn、signOut、error等固定配置项,删除该冗余配置即可。
6. 调试日志查看
开启debug: true后,后端日志会输出到服务器控制台(而非浏览器控制台);前端日志不显示是因为redirect: true导致页面跳转,设置redirect: false后即可在浏览器控制台看到signInData的输出。
内容的提问来源于stack exchange,提问作者Xhris

