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

Spring Boot 2.7.10+Spring Security登出重定向的CORS错误问题

问题描述

我有两个应用:

  • 后端服务:Spring Boot应用,运行地址 http://localhost:8080/server
  • 前端客户端:JavaScript应用,运行地址 http://localhost:9000/app

客户端可通过自定义登录表单携带凭证正常登录,也能使用fetch() API向后端8080端口请求JSON数据。但点击登出按钮时,向后端发送类似 http://localhost:8080/server/logout?originalClientURL=http://localhost:9000/app 的请求后,后端处理重定向到客户端时出现CORS错误:

Access to XMLHttpRequest at 'http://localhost:900/app/'
(redirected from 'http://localhost:8080/server/logout?originalClientURL=http://localhost:9000/app/')
from origin 'http://localhost:9000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

我的Spring Security配置代码如下:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

            http.cors(cors -> cors.configurationSource(request -> {
                CorsConfiguration configuration = new CorsConfiguration();
                configuration.setAllowedOrigins(Arrays.asList("*"));
                configuration.setAllowedMethods(Arrays.asList("*"));
                configuration.setAllowedHeaders(Arrays.asList("*"));
                return configuration;
            }))
                    .csrf()
                    .disable();

            http
            .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // 避免Spring默认的POST方式登出表单
                .addLogoutHandler((request, response, authentication) -> {
                
                    // 登出前在服务器执行一些操作

                    // 之后重定向回客户端地址
                    String originalClientURL = request.getParameterMap().get("originalClientURL")[0];
                    response.sendRedirect(originalClientURL);

        });
    
    }

}
解决方案

问题核心是:用fetch()发送登出AJAX请求时,浏览器会自动跟随重定向,但重定向后的前端地址(9000端口)不会返回CORS响应头,导致跨域拦截。下面是两种可行的解决方式:

方案1:后端返回跳转地址,前端自行处理(推荐)

不要让后端直接重定向,改为返回包含跳转地址的JSON响应,由前端主动跳转,避免AJAX跨域重定向的问题:

后端修改登出处理器

.addLogoutHandler((request, response, authentication) -> {
    // 执行登出前的业务操作
    String originalClientURL = request.getParameter("originalClientURL");
    
    // 设置CORS响应头,确保前端能接收这个响应
    response.setHeader("Access-Control-Allow-Origin", "http://localhost:9000");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setContentType("application/json");
    // 返回跳转地址
    response.getWriter().write("{\"redirectUrl\":\"" + originalClientURL + "\"}");
})

前端修改fetch请求逻辑

fetch('http://localhost:8080/server/logout?originalClientURL=http://localhost:9000/app', {
  method: 'GET',
  credentials: 'include' // 携带会话凭证,确保登出生效
})
.then(res => res.json())
.then(data => {
  window.location.href = data.redirectUrl; // 前端主动跳转
})
.catch(err => console.error(err));

方案2:强制后端重定向响应携带CORS头(不推荐)

如果一定要用后端重定向,需要在sendRedirect前给响应添加CORS头,确保浏览器能接受这个重定向响应:

.addLogoutHandler((request, response, authentication) -> {
    // 执行登出前的业务操作
    String originalClientURL = request.getParameter("originalClientURL");
    
    // 添加CORS头到重定向响应
    response.setHeader("Access-Control-Allow-Origin", "http://localhost:9000");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    // 暴露Location头,让前端可以获取重定向地址(可选)
    response.setHeader("Access-Control-Expose-Headers", "Location");
    
    response.sendRedirect(originalClientURL);
})

注意:这种方式要求前端应用本身能返回CORS头,但前端一般是静态页面或SPA,很少配置这类头,所以方案1更稳妥。

补充:优化全局CORS配置

不要用*允许所有来源,明确指定前端地址更安全,同时开启凭证支持:

http.cors(cors -> cors.configurationSource(request -> {
    CorsConfiguration configuration = new CorsConfiguration();
    // 明确指定允许的前端域名,支持多个可添加多个地址
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:9000"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("*"));
    // 允许携带会话凭证(如cookie、token)
    configuration.setAllowCredentials(true);
    return configuration;
}))

内容的提问来源于stack exchange,提问作者Bằng Rikimaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:43:12