NextAuth使用CredentialsProvider登录时无法跳转至新用户页面如何解决?
问题:使用CredentialsProvider登录时无法跳转到新用户页面
我在使用NextAuth的CredentialsProvider登录时,遇到了无法跳转到新用户页面的问题。authorize函数确实会为新用户返回isNewUser: true的标识,但跳转始终指向根路径/,从未指向配置的/auth/new-user。
我的NextAuth配置代码如下:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import axios from "axios"; export const authOptions = { providers: [ CredentialsProvider({ id: "magic-link", name: "Magic Link", credentials: { token: { label: "Token", type: "text", placeholder: "Paste your magic link token here", }, }, authorize: async (credentials) => { try { // Validate the token with the backend const response = await axios.get( `http://localhost:3001/auth/magic-link?token=${credentials.token}` ); const { user, backendTokens, isNewUser } = response.data; return { ...user, backendTokens, isNewUser }; } catch (error) { console.error("Error validating magic link:", error); return null; } }, }), CredentialsProvider({ id: "google", name: "Google", credentials: { query: { label: "Query", type: "text" }, }, authorize: async (credentials) => { try { // Forward the entire query string to the backend const response = await axios.get( `http://localhost:3001/auth/google/callback?${credentials.query}` ); const { user, backendTokens, isNewUser, expiresIn } = response.data; console.log("Magic link response", { user, backendTokens, isNewUser, expiresIn, }); return { ...user, backendTokens, isNewUser }; } catch (error) { console.error("Error during Google authentication:", error); return null; } }, }), ], callbacks: { async jwt({ token, user }) { console.log("JWT callback", { token, user }); // Check if this is the first time the JWT callback is called (user is defined) if (user) { token.user = user; if (user.backendTokens) { token.accessToken = user.backendTokens.accessToken; token.refreshToken = user.backendTokens.refreshToken; } } return token; }, async session({ session, token }) { console.log("Session callback", { session, token }); session.user = token.user; session.accessToken = token.accessToken; session.refreshToken = token.refreshToken; return session; }, async redirect({ url, baseUrl }) { console.log("Redirect callback", { url, baseUrl }); // Check if the URL is a callback URL if (url.startsWith(baseUrl)) { return baseUrl; } return url; }, }, pages: { signIn: "/auth/signin", newUser: "/auth/new-user", }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
我使用NestJS后端实现邮件发送、令牌生成和认证功能,魔法链接指向/auth/magic-link端点。
解决方法
1. 修复redirect回调的强制跳转逻辑
当前的redirect回调无条件返回baseUrl(根路径),直接覆盖了NextAuth默认的新用户跳转逻辑。需要修改该回调,根据isNewUser标识决定跳转目标:
async redirect({ url, baseUrl, token }) { console.log("Redirect callback", { url, baseUrl, token }); // 如果是新用户,跳转到新用户页面 if (token?.isNewUser) { return `${baseUrl}/auth/new-user`; } // 其他情况保持正常跳转逻辑 if (url.startsWith(baseUrl)) { return url; } return baseUrl; }
2. 确保isNewUser被正确传递到token中
在jwt回调中,需要将isNewUser直接挂载到token顶层,而非嵌套在token.user里,这样redirect回调才能正确读取该值:
async jwt({ token, user }) { console.log("JWT callback", { token, user }); if (user) { token.user = user; token.isNewUser = user.isNewUser; // 单独挂载isNewUser到token顶层 if (user.backendTokens) { token.accessToken = user.backendTokens.accessToken; token.refreshToken = user.backendTokens.refreshToken; } } return token; }
3. 验证pages.newUser配置路径
确认pages配置中的newUser路径与实际页面文件路径完全一致,避免路径拼写错误导致跳转失败。
4. 清除缓存并测试
- 清除浏览器缓存,重启Next.js开发服务(可使用
next dev --no-cache跳过缓存) - 测试新用户登录流程,查看控制台中
redirect回调的日志,确认isNewUser值是否正确传递
内容的提问来源于stack exchange,提问作者Bhavik Shah
相关产品推荐
相关产品推荐

