【问题标题】:Websocket connection with authorization header带有授权标头的 Websocket 连接
【发布时间】:2021-03-04 04:19:42
【问题描述】:

我正在开发一个实时 websocket 应用程序,在该应用程序中,服务器使用 .Net 核心进行编码,而客户端可以使用多种不同的语言。我决定保护服务器的方式是 JWT,即只接受来自具有有效 JWT 的请求的套接字连接。我可以使用 .Net 客户端成功地做到这一点,这是我的代码:

        _client = new WebSocket("ws://localhost:8080/api/SocketDock","",null,new List<KeyValuePair<string, string>>()
        { new KeyValuePair<string, string>(
            "Authorization", "Bearer eyJhbGciOiJIUzI1.....") 
        });

这与 .net 核心客户端 websocket 完美配合。但是,我不能对 Angular 客户端做同样的事情。我浏览了几篇文章,最终得到了一个不可能的答案。但是,在我看来,如果协议或握手在一种语言中是可能的,那么在其他语言中也一定是可能的。

有人可以指导我以正确的方式使用任何 Angular 客户端实现相同的目标吗?

【问题讨论】:

    标签: angular websocket header jwt


    【解决方案1】:

    答案是 javascript 原生 websocket api 不支持添加自定义标头,因为它根本没有必要。

    https://stackoverflow.com/a/4361358/10982972

    您可以通过首先通过可以具有该授权标头的 get api 获取它来共享它查询参数的令牌。

    参考:-

    https://stackoverflow.com/a/39816150/10982972

    如果您认为 websocket 在 url 中有令牌不安全,请参阅此处:-

    https://support.ably.com/support/solutions/articles/3000075120-is-it-secure-to-send-the-access-token-as-part-of-the-websocket-url-query-params-

    Chromme 的 Websocket 的官方维护者没有使用它的原因:-

    https://github.com/whatwg/html/issues/3062#issuecomment-332065542

    您可以通过 stompJS 等其他客户端实现添加标题。

    喜欢这里 :- https://github.com/stomp-js/ng2-stompjs/issues/83#issuecomment-421210171

    这里有一个完整的 Spring Boot 后端示例:-

    https://www.javaguides.net/2019/06/spring-boot-angular-8-websocket-example-tutorial.html

    【讨论】:

      【解决方案2】:

      您不能为安全问题添加自定义标头,WebSocket API 不支持它。

      您可以做的是像这样在 URL 中传递您的令牌:

      new WebSocket("ws://localhost:8080/api/SocketDock?authorization=eyJhbGciOiJIUzI1...")
      

      更完整的答案here

      【讨论】:

      • 文档没有说明不允许使用标头。这里的重点是,由于 websocket 请求以 http 请求开始,然后升级为 websocket,因此应该可以将 headers 连同它一起发送。
      • 如您所见 here,您无法从 JavaScript 自定义 WebSocket 标头,您仅限于从浏览器发送的“隐式”身份验证(即基本或 cookie)。
      • 这正是我想要做的,即与请求一起发送 cookie 或基本身份验证标头。你能告诉我怎么可能吗
      • @MurtuzaKabul 浏览器会自动包含 Cookie,具体取决于 Cookie 的选项
      【解决方案3】:

      您可以使用 RxJs 的 webSocket 和 webSocketSubject 来实现您的 Angular 应用程序和服务器之间通过 ws 协议进行 ws 通信。

      您可以通过负载将 JWT 令牌发送到服务器到 webSocket 的 next() 函数。

      send(data: any) {
          if (this.connection$) {
              const payload = {
                token: this.authService.token,
                ...data,
              };
              
              this.connection$.next(payload);
          }
      }
      

      briebug 上的article here 详细解释了创建 ws 连接的步骤,将 JWT 令牌作为有效负载的一部分发送。

      【讨论】:

      • 不是一个选项。正如我所解释的,有必要将令牌作为标头发送,而不是使用打开的 websocket 连接,因为预期的行为是在请求未通过身份验证时不让套接字升级发生。
      猜你喜欢
      • 2015-03-23
      • 2014-06-22
      • 2014-12-25
      • 2018-04-10
      • 2012-03-22
      • 2017-12-03
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      相关资源
      最近更新 更多