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

Spring Boot使用AuthenticationSuccessHandler跳转React外部URL及CORS问题求助

问题根因

  1. 你配置的formLogin.successHandler仅对Spring Security自带的表单登录流程生效,你自定义了CustomAuthenticationFilter处理登录请求,请求链路根本不会走到formLogin对应的逻辑分支,所以跳转配置不生效。
  2. 前后端分离场景下,前端通过AJAX/axios发送登录请求时,后端返回的302重定向会被浏览器自动执行,不会通知前端业务逻辑,而且跨域场景下自动跳转的请求会触发CORS报错,完全不符合你的预期。
  3. 你当前的CORS配置仅使用了默认规则,未放行自定义请求头、跨域凭证等配置,也会导致跨域错误。

解决方案

后端调整

  1. 删掉无用的http.formLogin()相关配置,JWT无会话模式下不需要服务端表单登录能力。
  2. 将登录成功后的返回逻辑移到CustomAuthenticationFilter的认证成功回调中,不要用sendRedirect,直接返回JSON格式的响应,携带JWT和跳转标识即可:
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    // 原有生成JWT的逻辑保留
    String jwt = yourJwtUtil.generateToken(authResult);
    
    response.setContentType("application/json;charset=utf-8");
    Map<String, Object> res = new HashMap<>();
    res.put("code", 200);
    res.put("token", jwt);
    res.put("success", true);
    // 可选返回跳转地址,也可以前端硬编码首页地址
    res.put("redirectUrl", "http://localhost:3000");
    response.getWriter().write(new ObjectMapper().writeValueAsString(res));
}
  1. 修正CORS配置,放行前端需要的跨域权限:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    // 生产环境替换为实际前端域名
    config.setAllowedOrigins(List.of("http://localhost:3000"));
    config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    config.setAllowedHeaders(List.of("*"));
    config.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

前端调整

登录请求拿到后端返回的成功响应后,由前端路由完成跳转,不要依赖后端重定向:

// 以react-router-dom v6为例
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

const LoginPage = () => {
  const navigate = useNavigate();
  
  const handleSubmit = async (loginForm) => {
    try {
      const res = await axios.post('http://localhost:8080/api/v1/login', loginForm);
      // 存储JWT到本地存储
      localStorage.setItem('access_token', res.data.token);
      // 前端主动跳转首页
      navigate('/');
    } catch (e) {
      console.error('登录失败', e);
    }
  }
  // 页面其他逻辑省略
}

前后端分离部署说明

你之前看到的跳转到本地HTML的教程都是单体应用的实现方案,不适用于前后端分离场景。分离部署模式下,后端仅负责提供数据接口和权限校验,页面路由、跳转逻辑全部由前端负责,不要在后端做重定向操作,避免跨域和跳转逻辑失效的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:45:01