我遇到了同样的问题,并使用 Spring Boot 2.5.4 和 Spring Cloud Gateway 2020.0.3 找到了以下解决方案:
为了独立于下游服务的 Cookie 命名,我决定重命名所有通过网关的 cookie。但为了避免下游请求(来自网关本身)中出现重复的会话 cookie,我还重命名了网关 cookie。
重命名网关会话 Cookie
很遗憾,customizing the gateway cookie name 使用 server.servlet.session.cookie.name 在当前网关版本中无法使用。
因此,注册一个自定义 WebSessionManager bean(需要的名称,因为自动配置取决于 bean 名称!)更改 cookie 名称(使用您喜欢的任何名称,除了典型的会话 cookie 名称,如 SESSION、JSESSION_ID、... ):
static final String SESSION_COOKIE_NAME = "GATEWAY_SESSION";
@Bean(name = WebHttpHandlerBuilder.WEB_SESSION_MANAGER_BEAN_NAME)
WebSessionManager webSessionManager(WebFluxProperties webFluxProperties) {
DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager();
CookieWebSessionIdResolver webSessionIdResolver = new CookieWebSessionIdResolver();
webSessionIdResolver.setCookieName(SESSION_COOKIE_NAME);
webSessionIdResolver.addCookieInitializer((cookie) -> cookie
.sameSite(webFluxProperties.getSession().getCookie().getSameSite().attribute()));
webSessionManager.setSessionIdResolver(webSessionIdResolver);
return webSessionManager;
}
重命名创建的 Cookies
下一步是重命名下游服务器设置的(所有)cookie。这很容易,因为有一个RewriteResponseHeader 过滤器可用。我决定简单地为每个 cookie 名称添加一个前缀(为每个下游选择一个唯一的):
filters:
- "RewriteResponseHeader=Set-Cookie, ^([^=]+)=, DS1_$1="
重命名发送的 Cookies
最后一步是在发送到下游服务器之前重命名 cookie。由于下游服务器的每一个cookie都有唯一的前缀,去掉前缀即可:
filters:
- "RewriteRequestHeader=Cookie, ^DS1_([^=]+)=, $1="
Arg,currently there is no such filter available。但是基于现有的RewriteResponseHeader 过滤器,这很容易(如果您将其注册为 bean,Cloud Gateway 将使用它):
@Component
class RewriteRequestHeaderGatewayFilterFactory extends RewriteResponseHeaderGatewayFilterFactory
{
@Override
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> rewriteHeaders(httpHeaders, config)).build();
return chain.filter(exchange.mutate().request(request).build());
}
@Override
public String toString() {
return filterToStringCreator(RewriteRequestHeaderGatewayFilterFactory.this)
.append("name", config.getName()).append("regexp", config.getRegexp())
.append("replacement", config.getReplacement()).toString();
}
};
}
private void rewriteHeaders(HttpHeaders httpHeaders, Config config)
{
httpHeaders.put(config.getName(), rewriteHeaders(config, httpHeaders.get(config.getName())));
}
}