113

Nginx反向代理WebSocket响应403的解决办法

 6 years ago
source link: https://segmentfault.com/a/1190000012634779?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Nginx反向代理WebSocket响应403的解决办法

在Nginx反向代理一个带有WebSocket功能的Spring Web程序(源代码地址)时,发现访问WebSocket接口时总是出现403响应,Nginx的配置参考的是官方文档:

http {
    // ssl 相关配置 ...
    
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 8020;
        location /ws {
            proxy_pass http://some-ip:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }
}

唯一不同的是我们的Nginx配置了https。

于是打开Spring日志查看直接访问和通过Nginx访问的差别。

直接访问的日志:

DEBUG ... o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/ws/gs-guide-websocket/786/kz0qai5l/websocket]
DEBUG ... s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /gs-guide-websocket/786/kz0qai5l/websocket
DEBUG ... s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/gs-guide-websocket/786/kz0qai5l/websocket]
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : Matching patterns for request [/gs-guide-websocket/786/kz0qai5l/websocket] are [/gs-guide-websocket/**]
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : URI Template variables for request [/gs-guide-websocket/786/kz0qai5l/websocket] are {}
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : Mapping [/gs-guide-websocket/786/kz0qai5l/websocket] to HandlerExecutionChain with handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@307f6b8c] and 1 interceptor
DEBUG ... o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/ws/gs-guide-websocket/786/kz0qai5l/websocket] is: -1
DEBUG ... o.s.web.cors.DefaultCorsProcessor        : Skip CORS processing: request is from same origin
DEBUG ... o.s.w.s.s.t.h.DefaultSockJsService       : Processing transport request: GET http://localhost:8080/ws/gs-guide-websocket/786/kz0qai5l/websocket
DEBUG ... o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG ... o.s.web.servlet.DispatcherServlet        : Successfully completed request

通过Nginx访问的日志:

DEBUG ... o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/ws/gs-guide-websocket/297/jp1c3ab5/websocket]
DEBUG ... s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /gs-guide-websocket/297/jp1c3ab5/websocket
DEBUG ... s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/gs-guide-websocket/297/jp1c3ab5/websocket]
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : Matching patterns for request [/gs-guide-websocket/297/jp1c3ab5/websocket] are [/gs-guide-websocket/**]
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : URI Template variables for request [/gs-guide-websocket/297/jp1c3ab5/websocket] are {}
DEBUG ... o.s.w.s.s.s.WebSocketHandlerMapping      : Mapping [/gs-guide-websocket/297/jp1c3ab5/websocket] to HandlerExecutionChain with handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@307f6b8c] and 1 interceptor
DEBUG ... o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/ws/gs-guide-websocket/297/jp1c3ab5/websocket] is: -1
DEBUG ... o.s.w.s.s.t.h.DefaultSockJsService       : Processing transport request: GET http://localhost:8080/ws/gs-guide-websocket/297/jp1c3ab5/websocket
DEBUG ... o.s.w.s.s.s.OriginHandshakeInterceptor   : Handshake request rejected, Origin header value https://some-host.com not allowed
DEBUG ... o.s.w.s.s.s.HandshakeInterceptorChain    : org.springframework.web.socket.server.support.OriginHandshakeInterceptor@25ce6ad4 returns false from beforeHandshake - precluding handshake
DEBUG ... o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG ... o.s.web.servlet.DispatcherServlet        : Successfully completed request

注意到直接访问的日志里有这么一条:

DEBUG ... o.s.web.cors.DefaultCorsProcessor        : Skip CORS processing: request is from same origin

通过Nginx访问的日志里有这么一条:

DEBUG ... o.s.w.s.s.s.OriginHandshakeInterceptor   : Handshake request rejected, Origin header value https://some-host.com not allowed

然后Google查询相关解决办法,找到github上的这个issue,所以只需要修改Nginx的配置,添加proxy_set_header Origin "";就行了:

http {
    // ssl 相关配置 ...
    
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 8020;
        location /ws {
            proxy_pass http://some-ip:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Origin "";
        }
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK