LoginSignup
0

React NativeのWebSocketは接続先のホストがOriginに使われる

Last updated at Posted at 2020-12-12

Origin ヘッダー、 CORS とは

ブラウザから JavaScript で別ドメインの API 、画像、音声ファイルなどのリソースを利用するときはもろもろの脆弱性(詳しくは割愛)を防ぐため、 CORS という仕組みを使いリクエストの Origin ヘッダーを見てアクセスを許可する場合のみレスポンスに Access-Control-Allow-Origin ヘッダーを返してあげる必要があります。

オリジン間リソース共有 (CORS)

これはブラウザのセキュリティを担保するためのものなので、ターミナルから curl コマンドを使ったリクエストや Node.js からのアクセスなどには関係ありません。つまり React Native にも基本的には関係ありません。

オリジン間のWebSocket

WebSocket には CORS が適用されないため、 Origin をヘッダーを見て意図しないオリジンからのアクセスを拒否するように WebSocket サーバー内で実装する必要があります。

これをしないと Cross-Site WebSocket Hijacking の危険性があります。

React Native の WebSocket の Origin って?

前述の通り 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

Android
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 には HASURA_GRAPHQL_CORS_DOMAIN 環境変数をセットすることでCORSを許可するドメインを指定できる機能があります。

GraphQL engine server config examples | Hasura GraphQL Docs

HASURA_GRAPHQL_CORS_DOMAIN をセットすると、同時に GraphQL Subscription の WebSocket 接続もその Origin 以外からは弾くようになっています。

Subscriptions | Hasura GraphQL Docs

この仕様は基本的にはありがたいのですが、 React Native の場合は CORS は関係ないはずなのに WebSocket のときのみ接続が弾かれてしまうという問題があり CORS の設定ができないでいました。

React Native からの WebSocket 接続があるときは、 WebSocket サーバー自体のドメインを許可する Origin に追加すればよさそうです。

まとめと宣伝

Hasura の CORS を設定すると WebSocket が接続できなくなる問題があるため Production checklist のうち CORS の設定だけできていなかったのですが、これで一通り実践できるようになりました :tada:

最後に宣伝です。
現在 TypeScript / Next.js / React Native / GraphQL / Hasura を使った開発現場で業務委託やインターンのエンジニアを募集しています。
興味がございましたら shinnoki までご連絡下さい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0