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

NextAuth登录成功后如何重定向至用户原访问页面?

问题解决:NextAuth登录后重定向回商品页及注册场景处理

一、核心问题:登录后未跳转到callbackUrl的原因

你的登录页(/login)没有正确传递URL中携带的callbackUrl参数给signIn方法,导致NextAuth默认跳转到首页。以下是修复步骤:

1. 修改登录页的表单提交逻辑

确保登录页(客户端组件)从URL查询参数中获取callbackUrl,并在调用signIn时传入该参数:

// app/login/page.js(客户端组件)
'use client'
import { useSearchParams } from 'next/navigation'
import { signIn } from 'next-auth/react'

export default function LoginPage() {
  const searchParams = useSearchParams()
  // 获取callbackUrl,默认值设为首页
  const callbackUrl = searchParams.get('callbackUrl') || '/'

  const handleLogin = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const email = formData.get('email')
    const password = formData.get('password')

    // 调用signIn时传入callbackUrl
    await signIn('credentials', {
      email,
      password,
      redirect: true,
      callbackUrl
    })
  }

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

2. 可选:添加Redirect回调增强安全性

在authOptions中添加redirect回调,确保重定向地址是同域名下的合法地址:

export const authOptions = {
  // ...现有配置
  callbacks: {
    // ...现有jwt、session回调
    async redirect({ url, baseUrl }) {
      // 仅允许同域名或相对路径的重定向
      if (url.startsWith(baseUrl)) return url
      if (url.startsWith('/')) return new URL(url, baseUrl).toString()
      return baseUrl
    }
  },
  // ...其余配置
}

二、注册后跳转的场景处理

如果用户从商品页→登录页→注册页,需要将callbackUrl从登录页传递到注册页,注册完成后自动登录并跳转回目标页面:

1. 登录页添加带callbackUrl的注册链接

在登录页中,注册跳转链接携带当前的callbackUrl参数:

// 登录页内的注册链接
<p>还没有账号?
  <a href={`/register?callbackUrl=${encodeURIComponent(callbackUrl)}`}>立即注册</a>
</p>

2. 注册页完成注册后自动登录并跳转

注册页(客户端组件)获取callbackUrl,创建用户后直接调用signIn完成登录并跳转:

// app/register/page.js(客户端组件)
'use client'
import { useSearchParams } from 'next/navigation'
import { signIn } from 'next-auth/react'
import connectDB from '@/lib/db'
import Customer from '@/models/Customer'
import bcrypt from 'bcrypt'

export default function RegisterPage() {
  const searchParams = useSearchParams()
  const callbackUrl = searchParams.get('callbackUrl') || '/'

  const handleRegister = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const name = formData.get('name')
    const email = formData.get('email')
    const password = formData.get('password')

    try {
      await connectDB()
      // 检查用户是否已存在
      const existingUser = await Customer.findOne({ email })
      if (existingUser) {
        alert('该邮箱已注册')
        return
      }
      // 加密密码并创建用户
      const hashedPwd = await bcrypt.hash(password, 10)
      await Customer.create({ name, email, password: hashedPwd, cart: [] })
      
      // 注册成功后自动登录并跳转到目标页面
      await signIn('credentials', {
        email,
        password,
        redirect: true,
        callbackUrl
      })
    } catch (err) {
      console.error('注册失败:', err)
      alert('注册出错,请重试')
    }
  }

  return (
    <form onSubmit={handleRegister}>
      <input type="text" name="name" required placeholder="姓名" />
      <input type="email" name="email" required placeholder="邮箱" />
      <input type="password" name="password" required placeholder="密码" />
      <button type="submit">注册</button>
    </form>
  )
}

三、验证逻辑检查

你的CredentialsProvider的authorize函数存在一个小问题:当用户不存在时,代码未正确返回值,需修改为:

async authorize(credentials, req) {
  const { email, password } = credentials
  try {
    await connectDB()
    const customer = await Customer.findOne({ email })
    // 修复:用户不存在时返回null
    if (!customer) return null

    const pwdComparisonResult = await bcrypt.compare(password, customer.password)
    if (pwdComparisonResult) {
      return customer
    }
    return null
  } catch (error) {
    console.log('error ', error);
    return null // 捕获错误时也返回null
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:50:09