带有授权标头的 Websocket 连接

Posted

技术标签:

【中文标题】带有授权标头的 Websocket 连接【英文标题】:Websocket connection with authorization header 【发布时间】: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 客户端实现相同的目标吗?

【问题讨论】:

【参考方案1】:

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

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

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

参考:-

https://***.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 连接,因为预期的行为是在请求未通过身份验证时不让套接字升级发生。

以上是关于带有授权标头的 Websocket 连接的主要内容,如果未能解决你的问题,请参考以下文章

在 React-Native 应用程序中使用带有授权标头的 Axios GET

Firefox 无法建立到 WSS 的连接

WebSocket简介

websocket._exceptions.WebSocketProxyException:通过代理连接失败状态:503

WebSocket JS 的自定义标头

使用 stunnel 和 Ratchet 保护 websocket。连接已关闭