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

NextAuth登录失败后如何保留callbackUrl实现原路由跳转?

解决NextAuth CredentialsProvider登录失败后丢失callbackUrl的问题

问题场景

  • 未认证用户访问受保护路由时,会成功重定向至登录页
  • 首次登录成功时,可正常跳转至原目标受保护路由
  • 首次登录失败后再次登录成功,无法跳转至原目标受保护路由

问题根源

登录失败时,NextAuth会重定向回登录页并携带error、code等错误参数,覆盖了原有URL中的callbackUrl,导致后续登录时无法获取到原目标受保护路由地址。


解决方案

1. 优化Login组件的callbackUrl存储逻辑

修改登录页的状态管理逻辑,无论是否存在登录错误,都优先保留callbackUrl,同时用localStorage做持久化缓存,防止页面刷新丢失:

export default function Login() {
  const [callbackUrl, setCallbackUrl] = useState('/protected/dashboard');
  const [error, setError] = useState('');

  useEffect(() => {
    const searchParams = new URLSearchParams(window.location.search);
    
    // 优先从URL参数读取callbackUrl
    const urlCallback = searchParams.get('callbackUrl');
    if (urlCallback) {
      setCallbackUrl(urlCallback);
      // 存入localStorage做持久化
      localStorage.setItem('nextauth-callback-url', urlCallback);
    } else {
      // URL中没有的话,尝试从localStorage读取缓存的地址
      const storedCallback = localStorage.getItem('nextauth-callback-url');
      if (storedCallback) {
        setCallbackUrl(storedCallback);
      }
    }

    // 处理登录错误提示
    const errorParam = searchParams.get('error');
    if (errorParam) {
      setError('Invalid username or password');
      toast.error('Please check username and password');
    }
  }, []);

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    await signIn("credentials", { 
      username, 
      password, 
      redirect: true, 
      callbackUrl: callbackUrl
    });
    // 登录成功后清除缓存的callbackUrl
    localStorage.removeItem('nextauth-callback-url');
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 你的表单输入、按钮等内容 */}
    </form>
  );
}

2. 手动控制登录失败后的重定向(可选)

将signIn的redirect参数设为false,手动处理登录结果,确保登录失败时重定向URL携带callbackUrl:

const handleSubmit = async (event: React.FormEvent) => {
  event.preventDefault();
  const result = await signIn("credentials", { 
    username, 
    password, 
    redirect: false, 
    callbackUrl: callbackUrl
  });

  if (result?.error) {
    // 登录失败,手动构造重定向URL,保留callbackUrl
    const redirectUrl = `/login?error=${result.error}&callbackUrl=${encodeURIComponent(callbackUrl)}`;
    window.location.href = redirectUrl;
  } else {
    // 登录成功,直接跳转目标路由
    window.location.href = callbackUrl;
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:20:13