gateway转发websocket显示403(Forbidden) 已解决

 因业务调整,需要在gateway中添加websocket的转发地址(PS:网上目前没有关于这个错误解决),原来的配置如下

代码可见,我在cors‐configurations配置了跨域信息,拦截所有请求,下面配置了websocket的路由规则。

代码如下

spring:
  application:
    name: api-gateway-server
  cloud:
    # 网关配置
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        cors‐configurations:
          '[/**]': # 匹配请求
            # allowedOrigins: "*"
            allowedOriginPatterns: '*' #跨域处理 允许所有的域
            allowCredentials: true # 是否允许携带cookie
            allowedMethods: # 支持的方法
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
      # 路由配置
      routes: # 集合
        - id: websocket-reader-connect
          uri: lb://library-system-reader
          order: 2
          predicates:
            - Path=/librarySystemReader/websocket端点/info/**
          filters:
            - StripPrefix= 1
        - id: websocket-reader
          uri: lb:ws://library-system-reader
          order: 3
          predicates:
            - Path=/librarySystemReader/websocket端点/**
          filters:
            - StripPrefix= 1

 前端报跨域问题,检查发现我在gateway和项目websocket中都配置了AllowedOriginPattern,导致出现了两个Access-Control-Allow-Origin响应头。websocket原配置如下

代码贴上

    //webSocket配置类
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册端点
        registry.addEndpoint("/librarySystemReader-websocket").setAllowedOriginPatterns("*").addInterceptors(new HttpHandShakeInterceptor()).withSockJS();
    }

我将websocket配置中的setAllowedOriginPattern删除,本以为会连接成功,重启之后Stomp的get info显示403(Forbidden)。

不是最终解决办法

方法一:查问题最后发现如果想使用websocket,gateway不能配置跨域,原因不太清楚,第一种办法只能将gateway中的跨域注释掉,测试连接成功。

 

10月26日解决问题

方法二:和一些大佬交流之后,想到一个办法:

在gateway中设置过滤器检测websocket地址,删除gateway配置的跨域信息,使用websocket的跨域配置,在gateway中配置过滤器,设置此过滤器优先级最低。拦截websocket的请求将gateway配置的跨域头移除。

websocket、gateway采用之前的配置。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class WebsocketFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().pathWithinApplication().toString();
        substring = path.substring(0, path.indexOf("/", path.indexOf("/", 2) + 1));
        //检测websocket请求
        if(substring.equals("/librarySystemReader/librarySystemReader-websocket")){
            if(CorsUtils.isCorsRequest(request)){
                //删除头信息
                ServerHttpResponse response = exchange.getResponse();
                response.getHeaders().remove("Access-Control-Allow-Origin");
                response.getHeaders().remove("Access-Control-Allow-Credentials");
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //注意我将优先级设置最低
        return 4;
    }
}

测试结果连接成功!

下面是简单解释了一下websocket和http区别

1、WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。

2、WebSocket是需要浏览器和服务器握手进行建立连接的。而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。

联系

3、WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当使用Spring Cloud Gateway转发WebSocket请求时,需要进行一些特殊配置。下面是一个简单的教程,演示了如何配置Spring Cloud Gateway转发WebSocket请求。 1. 首先,确保你已经有一个基本的Spring Cloud Gateway项目,并且已经添加了必要的依赖。 2. 在你的Gateway配置类中,添加一个`@Bean`方法来创建一个`WebSocketHandlerMapping`的实例。这个实例将用于将WebSocket请求转发到相应的目标服务。 ```java @Configuration public class GatewayConfig { @Bean public WebSocketHandlerMapping webSocketHandlerMapping() { Map<String, WebSocketHandler> handlerMap = new HashMap<>(); // 添加需要转发WebSocket处理器 handlerMap.put("/ws-endpoint", new MyWebSocketHandler()); // 创建WebSocketHandlerMapping实例,并设置handlerMap SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(Ordered.HIGHEST_PRECEDENCE); mapping.setUrlMap(handlerMap); return mapping; } } ``` 请替换`MyWebSocketHandler`为你自己实现的WebSocket处理器。 3. 在Gateway配置文件中,添加以下配置来启用WebSocket支持和设置路由规则。 ```yaml spring: cloud: gateway: routes: - id: websocket_route uri: lb://websocket-service predicates: - Path=/ws-endpoint/** filters: - WebSocket=ws-endpoint ``` 这里的`websocket_route`是路由的ID,`lb://websocket-service`是目标WebSocket服务的地址,`/ws-endpoint/**`是需要转发WebSocket请求路径。请根据你的实际情况进行修改。 4. 在你的WebSocket服务项目中,实现一个WebSocket处理器作为目标处理器。例如: ```java @Component public class MyWebSocketHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理WebSocket消息 session.sendMessage(new TextMessage("Hello, WebSocket!")); } } ``` 这里的`handleTextMessage`方法用于处理收到的WebSocket消息。 5. 最后,启动你的Gateway服务和WebSocket服务,并尝试发送一个WebSocket消息到`/ws-endpoint`路径。如果一切配置正确,Gateway应该会将该消息转发WebSocket服务,并返回处理结果。 希望这个简单的教程能帮助到你实现Spring Cloud GatewayWebSocket转发功能。如有任何疑问,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值