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
相关产品推荐
相关产品推荐

