使用Next-Auth Credentials:默认页面下登录/登出后如何重定向?
解决方案
1. 首页登录按钮跳转至内置Credentials登录页
直接通过链接跳转至NextAuth内置的Credentials登录页面,并携带登录成功后的回调URL,避免调用signIn()时因缺少凭据触发错误:
// pages/index.tsx import Link from 'next/link'; export default function Home() { return ( <div> <Link href="/api/auth/signin/credentials?callbackUrl=/dashboard/beers"> <button>登录</button> </Link> </div> ); }
如果偏好使用signIn()函数(NextAuth v4+支持),确保调用时仅指定provider和callbackUrl,不传递凭据参数,此时会自动跳转到登录表单:
// pages/index.tsx import { signIn } from 'next-auth/react'; export default function Home() { return ( <div> <button onClick={() => signIn('credentials', { callbackUrl: '/dashboard/beers' })}> 登录 </button> </div> ); }
2. 登录成功跳转指定URL
通过上述方法传递callbackUrl参数后,登录成功时NextAuth会自动跳转到该地址。如果需要统一所有Credentials登录的跳转目标,可在signIn回调中处理:
// [...nextauth].ts callbacks: { async signIn({ user, account }) { // 仅对Credentials登录生效 if (account?.provider === 'credentials' && user) { return '/dashboard/beers'; } return true; }, // ...其他回调 }
3. 登出后重定向至登录页
在调用signOut()时指定回调URL,或者通过redirect回调统一处理登出请求:
方法一:客户端调用时指定
// 任意页面的登出按钮 import { signOut } from 'next-auth/react'; <button onClick={() => signOut({ callbackUrl: '/api/auth/signin' })}>登出</button>
方法二:全局配置(推荐)
在[...nextauth].ts的redirect回调中判断请求类型,自动处理登出跳转:
// [...nextauth].ts callbacks: { async redirect({ url, baseUrl, params }) { // 处理登出请求,重定向到登录页 if (params?.action === 'signout') { return `${baseUrl}/api/auth/signin`; } // 登录成功时,若没有指定callbackUrl则跳转到默认目标 if (url === baseUrl) { return `${baseUrl}/dashboard/beers`; } return url; }, // ...其他回调 }
4. 优化authorize函数健壮性
修改authorize函数,先判断凭据是否存在,避免空凭据触发不必要的错误:
// [...nextauth].ts - CredentialsProvider的authorize方法 async authorize(credentials, req) { // 缺少邮箱或密码时直接返回null if (!credentials?.email || !credentials?.password) { return null; } const collection = await getDbCollection("users"); const { email, password } = credentials; try { const user = await collection.findOne({ email, pwd: password }) as UserData; if (!user) { throw new Error("Invalid Login"); } return { id: user._id as string, name: user.name, email: user.email, role: user.role, domain: user.domain }; } catch (error) { throw new Error("Invalid Login"); } }
内容的提问来源于stack exchange,提问作者m3.b
相关产品推荐
相关产品推荐

