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

NextAuth Credentials登录成功后无跳转无日志问题排查求助

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:35:55