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

next-auth(v5)中signIn回调未触发,自定义登录校验失效

NextAuth v5 SignIn回调未触发的问题解决

问题场景

  • 使用NextAuth v5搭建了Github OAuth登录,功能正常运行
  • 想要实现「仅允许自己的Github账号登录」,在callbacks中定义了signIn回调,测试时设置该回调始终返回false,但Github账号仍能登录成功,且console.log无输出,说明回调未被激活

用户代码:

import NextAuth from "next-auth";
import { authConfig } from "./config";
import { db } from "~/server/db";
import { PrismaAdapter } from "@auth/prisma-adapter";

export const { auth, handlers, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  session: { strategy: "jwt" },
  callbacks: {
    signIn: async ({ user }) => {

      console.log("Forcibly fail authentication");
      return false;
    },
    session: async ({ session, token }) => ({
      ...session,
      user: {
        ...session.user,
        id: token.sub,
      },
    }),
  },
  pages: {
    signIn: "/signin",
  },
  ...authConfig,
});

问题原因

你使用了...authConfig扩展运算符,如果authConfig文件中已经定义了callbacks配置,它会直接覆盖你当前代码中写的callbacks,导致自定义的signIn回调根本没被加载生效。

解决方案

方案1:合并回调配置

将authConfig中的现有回调与自定义回调合并,避免被覆盖:

import NextAuth from "next-auth";
import { authConfig } from "./config";
import { db } from "~/server/db";
import { PrismaAdapter } from "@auth/prisma-adapter";

// 合并authConfig中的回调,添加自定义signIn逻辑
const mergedCallbacks = {
  ...authConfig.callbacks,
  signIn: async ({ user }) => {
    console.log("触发SignIn回调");
    // 替换为你的Github账号邮箱,仅匹配时允许登录
    const allowedEmail = "your-github-email@example.com";
    return user.email === allowedEmail;
  },
  session: async ({ session, token }) => ({
    ...session,
    user: {
      ...session.user,
      id: token.sub,
    },
  }),
};

export const { auth, handlers, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  session: { strategy: "jwt" },
  callbacks: mergedCallbacks,
  pages: {
    signIn: "/signin",
  },
  // 仅扩展authConfig中除callbacks外的其他配置
  ...(({ callbacks, ...rest }) => rest)(authConfig),
});

方案2:调整配置顺序

如果authConfig中没有定义callbacks,直接将自定义callbacks放在...authConfig之后,确保优先级更高:

import NextAuth from "next-auth";
import { authConfig } from "./config";
import { db } from "~/server/db";
import { PrismaAdapter } from "@auth/prisma-adapter";

export const { auth, handlers, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  session: { strategy: "jwt" },
  pages: {
    signIn: "/signin",
  },
  ...authConfig,
  // 把callbacks放在扩展运算符之后,避免被覆盖
  callbacks: {
    signIn: async ({ user }) => {
      console.log("触发SignIn回调");
      const allowedEmail = "your-github-email@example.com";
      return user.email === allowedEmail;
    },
    session: async ({ session, token }) => ({
      ...session,
      user: {
        ...session.user,
        id: token.sub,
      },
    }),
  },
});

关键提醒

NextAuth配置中,后定义的属性会覆盖先定义的属性。如果authConfig包含callbacks,...authConfig会直接冲掉你前面写的callbacks,所以一定要确保自定义回调最终保留在配置中。

内容的提问来源于stack exchange,提问作者Mikoshiba-Kyu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:03:24