使用Next Auth自定义登录页时出现TypeError: resolver is not a function错误
解决NextAuth + T3栈中TypeError: resolver is not a function错误
访问登录页时触发Server Error,报错信息为TypeError: resolver is not a function,使用T3栈搭配NextAuth开发,相关代码如下:
相关代码
[...nextauth].ts
export const authOptions: NextAuthOptions = { // Include user.id on session callbacks: { session({ session, user }) { if (session.user) { session.user.id = user.id; } return session; }, }, // Configure one or more authentication providers adapter: PrismaAdapter(prisma), providers: [ GoogleProvider({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }), DiscordProvider({ clientId: env.DISCORD_CLIENT_ID, clientSecret: env.DISCORD_CLIENT_SECRET, }), /** * ...add more providers here * * Most other providers require a bit more work than the Discord provider. * For example, the GitHub provider requires you to add the * `refresh_token_expires_in` field to the Account model. Refer to the * NextAuth.js docs for the provider you want to use. Example: * @see https://next-auth.js.org/providers/github */ ], pages: { signIn: "/auth/signin", }, };
登录触发按钮
<ul> ... other buttons ... <li> <button onClick={() => { session ? signOut() : signIn() }} className="bla bla bla"/> </li> </ul>
登录页组件
const SignIn: NextPage<{ providers: AppProps }> = ({ providers }) => { return ( <> <main className="h-screen"> <div className="container h-full px-6 py-24"> <div className="g-6 flex h-full flex-wrap items-center justify-center lg:justify-between"> <div className="md:w-8/12 lg:ml-6 lg:w-5/12"> <form> <div className="relative mb-6" data-te-input-wrapper-init> <input type="text" className="bla bla bla" id="exampleFormControlInput3" placeholder="Email address" /> <label htmlFor="exampleFormControlInput3" className="bla bla bla" >Email address </label> </div> <div className="mb-6 flex items-center justify-between"> <div className="bla bla bla"> <input className="bla bla bla" type="checkbox" value="" id="exampleCheck3" checked /> <label className="bla bla bla" htmlFor="checkBox"> Remember me </label> <button type="submit" className="bla bla bla" data-te-ripple-init data-te-ripple-color="light"> Send sign-in email link </button> <div className="bla bla bla"> <p className="bla bla bla"> OR </p> </div> <div> {Object.values(providers).map((provider) => ( <button data-te-ripple-init data-te-ripple-color="light" className="bla bla bla" style={{ backgroundColor: "#3b5998" }} key={provider.id} onClick={() => signIn(provider.name, { callbackUrl: `${window.location.origin}` })}> Sign in with {provider.name} </button> ))} </div> </div> </div> </form> </div> </div> </div> </main> </> ); }; export default SignIn; export const getServerSideProps: GetServerSideProps = async () => { const providers = await getProviders(); return { props: { providers }, }; };
错误原因及修复方案
该错误主要由NextAuth路由导出不完整、getProviders调用参数缺失或signIn参数错误导致,修复步骤如下:
1. 完善[...nextauth].ts的路由导出
在[...nextauth].ts文件末尾添加NextAuth的路由导出,确保API路由能正确处理认证请求:
export default NextAuth(authOptions);
2. 修正登录页getServerSideProps的getProviders调用
getProviders需要传入配置好的authOptions才能正确获取登录提供商列表,修改登录页的getServerSideProps:
import { authOptions } from "../api/auth/[...nextauth]"; // 根据实际文件路径调整导入 export const getServerSideProps: GetServerSideProps = async () => { const providers = await getProviders(authOptions); // 传入authOptions参数 return { props: { providers }, }; };
3. 调整signIn的调用参数
登录页中调用signIn时,应使用provider.id而非provider.name,避免因提供商名称与ID不匹配导致的错误:
onClick={() => signIn(provider.id, { callbackUrl: `${window.location.origin}` })}
额外检查项
- 确保
next-auth、@next-auth/prisma-adapter等依赖版本匹配,避免版本冲突引发的异常。 - 验证环境变量(如GOOGLE_CLIENT_ID、DISCORD_CLIENT_ID等)是否正确加载,未正确初始化的提供商可能间接触发resolver错误。
内容的提问来源于stack exchange,提问作者ClarenceHD
相关产品推荐
相关产品推荐

