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

AngularJS+SpringMVC SSO场景下CORS导致登出/会话失效无法跳转问题

问题根因说明

你遇到的CORS错误核心是两个原因:

  • 会话无效时,后端直接返回302重定向到SSO登录域名,浏览器发送AJAX请求时会自动跟随重定向,跨域请求目标SSO域名没有配置允许当前应用域名的CORS规则,直接被浏览器同源策略拦截,不会走到你写的响应拦截器逻辑
  • 前端AJAX请求默认没有携带Cookie,后端无法正确识别会话状态,也会触发无效会话逻辑
修复步骤

第一步:后端SpringMVC 5.x 配置调整

1. 全局CORS配置

新增CORS配置类,允许前端域名跨域访问、携带凭证:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 替换为你实际前端部署的域名,不要用*,否则无法开启凭证携带
                .allowedOrigins("http://你前端应用的域名:端口")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

2. 修改会话拦截逻辑,禁止AJAX请求返回302

调整你的SSO会话拦截器/过滤器逻辑:如果是AJAX请求(请求头带X-Requested-With: XMLHttpRequest),会话无效时直接返回401状态码,不要重定向到SSO登录页,只有普通页面请求才返回302重定向。

// 会话拦截器示例逻辑
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (会话无效) {
        String xRequestedWith = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equals(xRequestedWith)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        } else {
            // 普通页面请求,正常重定向到SSO登录页
            response.sendRedirect("http://login.boshiftdev.com/app/ui/login.jsp");
            return false;
        }
    }
    return true;
}

3. Tomcat可选配置

如果使用Tomcat内置的CORS过滤器,需要在web.xml中配置允许凭证、指定允许的域名,不要用通配符。

第二步:前端AngularJS代码调整

1. 全局配置$http携带凭证

在应用配置块开启withCredentials,保证AJAX请求自动携带Cookie:

TestApp.config(function($httpProvider) {
    $httpProvider.defaults.withCredentials = true;
    // 统一添加AJAX请求标识,方便后端判断
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

2. 修正响应拦截器逻辑

TestApp.factory('respInterceptor', function($location, $window, $cookies) {
    return {
        response: function(resp) {
            return resp;
        },
        responseError : function(error) {
            console.log(" Error >>> : "+error.status )
            if(error.status == 401) {
                // 修正原代码Cookie名拼写错误
                $cookies.remove('JSESSIONID');
                console.log("invalid session");
                // 直接跳转登录页,不会触发跨域
                window.location.href = "http://login.boshiftdev.com/app/ui/login.jsp";
            }
            return Promise.reject(error);
        }
    };
})
// 注册拦截器
TestApp.config(function($httpProvider) {
    $httpProvider.interceptors.push('respInterceptor');
});

3. 修正登出逻辑

$scope.logout = function() { 
    $cookies.remove('JSESSIONID');
    console.log("logout"); 
    $http({
        method: 'POST',
        url: contextURL+'/logout',
        headers: {'Content-Type': 'application/json'}, 
        params: {data: $rootScope.userSession }
    }).then(function successCallback(response) {
        $rootScope.userSession = null;
        window.location.href = "http://login.boshiftdev.com/app/ui/login.jsp";
    }, function errorCallback(response) {
        $rootScope.userSession = null;
        window.location.href = "http://login.boshiftdev.com/app/ui/login.jsp";
        console.error('登出请求失败');
    });
}
效果验证

调整后会话无效时后端直接返回401,不会触发跨域重定向,前端拦截器收到401后主动跳转到SSO登录页,即可解决CORS报错问题。
CORS Error

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:45:03