【问题标题】:Spring boot with nginx wss not working from angular使用 nginx wss 的 Spring Boot 无法从角度工作
【发布时间】:2022-11-09 08:01:04
【问题描述】:

我的 spring boot websocket(ws) 端点可以在 localhost 上使用 angular (rxstomp) 正常工作。

prod 服务器使用 nginx (https),​​我无法连接到 ws。 FE 和 BE 在 docker 中的同一台服务器上,在不同的 url 上。

Nginx 配置:

location /ws {

 ...

 proxy_pass http://backend/ws

 ...

}
BE: 

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOrigins(frontendUrl);
    }

FE: 

export function rxStompServiceFactory() {
    const rxStomp = new RxStompService();
    rxStomp.configure(myRxStompConfig);
    rxStomp.activate();
    return rxStomp;
}
export const myRxStompConfig: RxStompConfig = {
    brokerURL: 'ws://localhost:8088/ws',
...

请帮忙

谢谢

【问题讨论】:

  • nginx 中的上游是如何定义的?你得到的错误是什么? nginx日志中的任何内容?
  • 上游 apitest { ip_hash;服务器 127.0.0.1:8085 max_fails=1 fail_timeout=6s;服务器 127.0.0.1:8086 max_fails=1 fail_timeout=6s;保活 16; }
  • LOG: 2022/10/17 14:30:31 [crit] 223719#223719: *2929 SSL_do_handshake() 在 SSL 握手时失败(SSL: error:14201044:SSL routines:tls_choose_sigalg:internal error),客户端:[IP],服务器:0.0.0.0:443
  • 如果我没看错的话,您在 apitest 上游定义的负载平衡后面有 2 台服务器。但是,proxypass 设置为后端,所以这里不匹配......

标签: angular spring-boot nginx wss ws


【解决方案1】:

首先,这是我们的解决方案,当然还有更好的解决方案,但它确实有效。

问题:

同一台服务器上的 BE(backend) 和 FE(frontend) 具有不同的 url。 (fe.app.com 和 be.app.com) 还有一个 nginx 代理。

FE 无法通过 websocket 连接到 BE。

所以流程:前端 --> nginx(be.app.com) --> 后端

主要问题是当我们想将 wss 连接到 spring boot 应用程序时的授权(承载令牌),因为无法在 wss 连接请求中发送自定义标头。

解决方案:

将令牌保存到 cookie 并在后端 TokenAuthorizationFilter 中使用它

(Here the token cookie name is Authorization)
  if (request.getCookies() != null) {
    for (Cookie c : request.getCookies()) {
      if (Objects.equals(c.getName(), "Authorization")) {
        if (!c.getValue().startsWith("Bearer"))
          authorizationHeader = "Bearer " + c.getValue();
      }
    }
  }

并使用它而不是 requestHeader 的 Authorization 参数。

This is the request header
String authorizationHeader = request.getHeader("Authorization");

所以现在我们可以在 cookie 中发送令牌,后端进行授权。

不错,但还有一个问题。 重要的是要知道 cookie 是如何工作的! (Share cookie between subdomain and domain)

nginx 配置也应该转发 cookie。 在这种情况下,我们从 FE (fe.app.com/wss) 调用 FE 域,并在 nginx 配置中将 proxy_pass 设置为 BE websocket 位置 (backendIp:port/ws)

因此 BE 获取 cookie 并用于授权。

我希望它有所帮助。 :)

【讨论】:

    猜你喜欢
    • 2021-04-27
    • 2020-11-30
    • 2019-05-31
    • 2021-09-16
    • 2021-11-02
    • 2020-02-09
    • 2019-01-23
    • 2020-10-17
    • 2019-04-06
    相关资源
    最近更新 更多