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

Spring Cloud Gateway中Session属性读写异常:自定义过滤器逻辑未执行

问题排查与解决方案

1. 响应式Session未被订阅执行

Spring Cloud Gateway是基于WebFlux的非阻塞响应式框架,exchange.getSession()返回的是Mono<WebSession>——响应式类型的核心特点是只有被订阅(subscribe)或者嵌入到响应式调用链中时,内部逻辑才会触发执行。

如果你的代码只是单独调用map()但没有把这个Mono和过滤器的后续逻辑绑定,比如:

// 错误写法:仅调用map,无订阅/链式传递
exchange.getSession().map(session -> {
    session.getAttributes().put("userId", "123");
    return session;
});
return chain.filter(exchange);

这种情况下map里的代码根本不会执行。正确的做法是把Session操作整合到过滤器的响应式链中:

// 正确写法:用flatMap绑定后续过滤器逻辑
return exchange.getSession().flatMap(session -> {
    session.getAttributes().put("userId", "当前用户ID");
    return chain.filter(exchange); // 继续执行下游过滤器/路由
});

2. 跨服务Session共享配置不完整

网关和下游服务共享Session必须满足两个核心条件:

  • 统一Session存储:所有服务(网关+下游)必须配置相同的分布式Session存储(比如Redis),添加依赖并配置:
    spring.session.store-type=redis
    spring.redis.host=你的Redis地址
    
  • Cookie共享配置:确保网关和下游服务的Session Cookie域名、路径一致,比如同域名下的服务可以配置:
    server.servlet.session.cookie.domain=.your-domain.com
    server.servlet.session.cookie.path=/
    
    WebFlux环境下的Cookie配置略有不同,可通过WebSessionManager自定义,或者依赖Spring Session的自动配置生效。

3. 过滤器顺序错误

如果自定义认证过滤器执行时机太晚(比如请求已经转发到下游之后),或者在Spring Security的Session过滤器之前执行,会导致Session操作无效。

可以通过路由配置直接绑定过滤器,确保它在路由转发前执行:

@Bean
public RouteLocator customRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("user-service", r -> r.path("/user/**")
                    .filters(f -> f.filter(new MyAuthenticationFilter()))
                    .uri("http://user-service:8080"))
            .build();
}

或者给过滤器类添加@Order(Ordered.HIGHEST_PRECEDENCE)注解,让它优先于其他过滤器执行。

4. 忽略了响应式错误处理

如果exchange.getSession()抛出异常(比如Redis连接失败),map里的逻辑会直接跳过,且默认不会输出日志。建议添加错误处理分支排查问题:

return exchange.getSession()
        .flatMap(session -> {
            session.getAttributes().put("userId", "123");
            return chain.filter(exchange);
        })
        .onErrorResume(ex -> {
            ex.printStackTrace(); // 打印错误栈排查问题
            return ServerWebExchangeUtils.setResponseStatus(exchange, HttpStatus.INTERNAL_SERVER_ERROR);
        });

5. 下游服务读取Session的方式错误

如果下游是Spring MVC(Servlet环境),需要确保读取的是分布式Session的属性,而非本地内存Session。直接使用request.getSession().getAttribute("userId")即可,但必须保证下游服务的Session配置(存储、Cookie)和网关完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:55:17