WebSocket通信しようとしてハマった話

WebSocketで通信するミニゲームを作っていてハマったので備忘録に書いておこうと思います。

今回はバックエンドをGoで、フロントをjavascriptで実装しています。 ファイル構成はこんな感じ。

src
├── static
│   └── connect4.html
├── client.go
├── hub.go
└── main.go

GoのWebSocketの仕組みはgorilla/websocketを使っていて、GitHubのexampleに書いているコードを参考にしています。

ハマりどころ

とりあえず動作を見てみるために次のようにサーバーとフロントを立ち上げたところ次のエラーが発生していました。

go run *.go
open static/connect4.html
  • フロント側のエラーメッセージ
WebSocket connection to 'ws://localhost:8080/ws' failed: Error during WebSocket handshake: Unexpected response code: 403
  • バッグエンドのエラーメッセージ
websocket: request origin not allowed by Upgrader.CheckOrigin

Web系知識が乏しいので何が悪いが全く分かりませんでしたが、 調べていくとどうやらCross-Originチェックという仕組みがあるらしく、これにハマっているようです。

Cross-Originチェック?

オリジンはスキーム、ホスト、ポートの組み合わせのこと。
Cross-Originチェックというのは簡単に言うと、Webページを開いたときに、そのページの関連するリソースを同一のオリジンからしか取得できないようにしてセキュリティ保護する仕組みのことらしいです。

developer.mozilla.org

今回やってみた方法だと、フロントはローカルのhtmlファイルを直接開いているので、 サーバのオリジンと異なっていてアクセスが許可されないことになります。 なるほど、確かになんでもアクセス許可出していたらセキュリティ的に問題がありますね。

  • フロントのURL
file:///Users/kota/go/src/github.com/bluemon0919/websocket/connect4/static/connect4.html
  • バッグエンドのURL
http://localhost:8080/

では、どうやって解決すればいいのか?
そもそも今回のような方法で使うのがいけないのだと思いますが、、、
CORS(オリジン間リソース共有)という仕組みを使えば異なるオリジン間でもリソースに対してアクセス権を与えることができるらしいです。

developer.mozilla.org

サーバ側でCORSに対応する必要がありそうですが、実装方法がわからないのでとりあえず以下のサイトを参考に修正してみました。
とりあえず動作をみることはできています。

https://nananao.com/entry/websocket-upgrader-corsnananao.com