React Native的WebSocket使用连接目标的主机作为Origin

源头标题、跨域资源共享 (CORS) 是什么

当在浏览器中使用JavaScript来访问不同域名的API、图像、音频文件等资源时,为了防止各种脆弱性(详细内容略),需要使用CORS机制来检查请求的Origin头,并只有在允许访问时才返回Access-Control-Allow-Origin头部到响应中。

跨源资源共享 (CORS)

这是为了确保浏览器安全而存在的,因此与利用终端的curl命令发送请求或从Node.js进行访问等无关。换句话说,基本上与React Native无关。

原点之间的WebSocket

由于WebSocket不适用CORS,因此WebSocket服务器需要在其内部实现通过检查头部中的Origin来拒绝来自意外来源的访问。

 

不做这个操作可能存在跨站WebSocket劫持的危险。

React Native的WebSocket的源代码是什么?

React Native 基本上不受 CORS 影响,但为了确保 WebSocket 连接的安全性,该怎样设置 Origin 头呢?

在文档中找不到描述,但观察到React Native的原生WebSocket实现时,发现它将WebSocket连接的地址从ws(s)替换为http(s)的字符串,并将其设置为Origin头部。

iOS
https://github.com/facebook/react-native/blob/v0.63.4/Libraries/WebSocket/RCTSRWebSocket.m#L1552-L1571

iOS
https://github.com/facebook/react-native/blob/v0.63.4/Libraries/WebSocket/RCTSRWebSocket.m#L1552至L1571

Android
https://github.com/facebook/react-native/blob/6e6443afd04a847ef23fb6254a84e48c70b45896/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.java#L105-L129

安卓
https://github.com/facebook/react-native/blob/6e6443afd04a847ef23fb6254a84e48c70b45896/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.java#L105-L129

从实现来看,如果在Android上JS传递了Origin头,则似乎会使用该值,但是在iOS上似乎没有这样的行为,所以最好不要传递Origin头。

为什么这个是必要的?

我們正在目前的項目中使用一個名為Hasura的中間件,它可以從PostgreSQL生成GraphQL API。通過設置HASURA_GRAPHQL_CORS_DOMAIN環境變量,Hasura可以指定允許CORS的域。

GraphQL引擎服务器配置示例 | Hasura GraphQL文档

设置 HASURA_GRAPHQL_CORS_DOMAIN 将同时阻止来自 Origin 以外的 WebSocket 连接到 GraphQL 订阅。

订阅 | Hasura GraphQL 文档

这个规范基本上是令人感激的,但对于React Native来说,CORS不应该是一个问题,然而只有在WebSocket连接时才出现了连接被拒绝的问题,这导致无法设置CORS的配置。

当有来自React Native的WebSocket连接时,只需要将WebSocket服务器的域名添加到允许的来源(Origin)中即可。

整理和宣传

由于设置了Hasura的CORS,导致无法连接WebSocket的问题,因此在生产检查清单中,我只设置了CORS并没有完成。现在,我已经可以完成全部实践。

最后,请允许我宣传一下。
我们正在使用TypeScript / Next.js / React Native / GraphQL / Hasura进行开发,并正在寻找业务托管或实习工程师。
如果您有兴趣,请联系shinnoki。

广告
将在 10 秒后关闭
bannerAds