gorilla/websocket で異なるOrgin間の Error during WebSocket handshake: Unexpected response code: 403 を回避する
はじめに
go の websocket サーバー gorilla/websocket に対して Angular の rxjs/webSocket を利用して簡単なチャットアプリを作成していたところ Error during WebSocket handshake: Unexpected response code: 403
なるエラーに遭遇しました。
結論としては websocket の upgrade の originチェックに引っかかっていたようです。その回避策をまとめます。
gorilla/websocket の CORS
websocket の handshake が失敗してそうなエラーで、同一orginにあるフロントエンドでは handshake が成功するので、CORSかな。と考えて以下のように書くわけです。
func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) { // Add CORS header... w.Header().Set( "Access-Control-Allow-Origin", r.RemoteAddr ) w.Header().Set( "Access-Control-Allow-Credentials", "true" ) w.Header().Set( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization" ) w.Header().Set( "Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS" ) conn, err := upgrader.Upgrade(w, r, nil) if err != nil { return } client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)} client.hub.register <- client go client.writePump() go client.readPump() }
が、ダメ。
WebSocket connection to 'ws://localhost:8080/ws/' failed: Error during WebSocket handshake: Unexpected response code: 403
websocket のhandshake 内のシーケンスで origin をチェックしているようで、以下のように雑にチェックしてあげることで接続できるようになりました。
var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, // Add this lines CheckOrigin: func(r *http.Request) bool { return true }, }
まとめ
gorilla/websocket の CORS エラーに対応してみました。
websocket 自体に認証の仕組みがないので、upgradeする前に orgin の検証やユーザー認証をしなさい。という感じのようです。