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

NextAuth v5 Credentials Provider登录后无法自动跳转问题

解决Next.js Credentials Provider登录后无法自动跳转至/dashboard的问题

1. 检查Server Actions中的登录逻辑

确保调用signIn时正确配置跳转参数,或在登录成功后触发会话刷新:

  • 如果希望直接由NextAuth处理跳转,设置redirect: true并指定callbackUrl:
'use server'
import { signIn } from '@/auth'

export async function loginAction(credentials: { email: string; password: string }) {
  await signIn('credentials', {
    ...credentials,
    redirect: true,
    callbackUrl: '/dashboard' // 指定登录成功后的跳转目标
  })
}
  • 如果手动处理跳转,设置redirect: false,登录成功后调用refreshSession更新会话状态:
'use server'
import { signIn, refreshSession } from '@/auth'

export async function loginAction(credentials: { email: string; password: string }) {
  const result = await signIn('credentials', {
    ...credentials,
    redirect: false
  })
  
  if (result?.ok) {
    await refreshSession() // 强制刷新会话,让客户端感知登录状态变化
    return { success: true }
  }
  
  return { error: result?.error || '登录失败' }
}

2. 在客户端登录页面监听会话状态变化

登录页面必须标记为客户端组件(添加'use client'指令),使用useSession钩子监听会话状态,当状态变为authenticated时触发跳转:

'use client'
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'
import { loginAction } from '@/app/actions/login'
import { FormEvent } from 'react'

export default function LoginPage() {
  const { status } = useSession()
  const router = useRouter()

  // 监听会话状态,认证成功后跳转
  useEffect(() => {
    if (status === 'authenticated') {
      router.push('/dashboard')
    }
  }, [status, router])

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault()
    const formData = new FormData(e.currentTarget)
    const credentials = {
      email: formData.get('email') as string,
      password: formData.get('password') as string
    }
    await loginAction(credentials)
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" name="email" required />
      <input type="password" name="password" required />
      <button type="submit">登录</button>
    </form>
  )
}

3. 验证NextAuth配置的正确性

确保auth.ts中的回调函数正确处理会话和令牌,保证会话状态能被正确识别:

import NextAuth from 'next-auth'
import Credentials from 'next-auth/providers/credentials'

export const { handlers, auth, signIn, signOut, refreshSession } = NextAuth({
  providers: [
    Credentials({
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' }
      },
      async authorize(credentials) {
        // 调用自定义后端验证凭证,返回包含令牌的用户对象
        const res = await fetch(`${process.env.BACKEND_URL}/login`, {
          method: 'POST',
          body: JSON.stringify(credentials),
          headers: { 'Content-Type': 'application/json' }
        })
        const user = await res.json()
        
        if (res.ok && user) {
          return { ...user, accessToken: user.accessToken, refreshToken: user.refreshToken }
        }
        return null
      }
    })
  ],
  callbacks: {
    async jwt({ token, user }) {
      // 初始化令牌
      if (user) {
        token.accessToken = user.accessToken
        token.refreshToken = user.refreshToken
      }
      // 此处添加令牌轮转逻辑
      return token
    },
    async session({ session, token }) {
      // 将令牌注入会话,供客户端/服务器使用
      session.user.accessToken = token.accessToken
      session.user.refreshToken = token.refreshToken
      return session
    }
  },
  pages: {
    signIn: '/login' // 确保登录页面路径与实际路由一致
  }
})

4. 排查路由与权限配置

  • 确保/dashboard页面使用auth中间件或useSession进行权限校验,避免未登录状态下直接访问,但不要阻止登录成功后的跳转。
  • 如果使用了Next.js App Router的中间件,检查中间件逻辑是否错误拦截了跳转请求。

内容的提问来源于stack exchange,提问作者Danish Shaikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:37:38