2018-03-13(火) [長年日記]
■ (自分で書いた)誤ったHTTPヘッダのせいで苦労した話
わさますのコミュニケーション基盤であるmassr、いまはHerokuで動かしているんだけど、長年の運用でMongoDBの容量も増えてきてコスト的にも厳しい感じになってきたので、VPSでも借りて引っ越そうという算段をしている。とりあえずGCE(Google Compute Engine)の無料枠でためそうかという流れに。
Dockerを使ってmassr本体とMongoDB、Memcachedはそれぞれ別のコンテナに入れ、reverse proxyとしてフロントに立てたnginxにhttpsをさばいてもらうという、(たぶん)昨今ではオーソドックスな構成。
で、普通に会話するくらいのところまでは問題なく動いたんだけど、フォームを経由しないLikeなんかの動作が403を返して失敗する。使い慣れないDocker上でいろいろ調べると、Rack::Csrfが403を返している。CSRFトークンが渡ってきてない。
ブラウザ上のjQuery*1はちゃんとHTTPヘッダにトークンを乗せている。でもmassrには渡ってきてない。てことは途中のnginxが怪しい?
調査過程はすっ飛ばして、結論から言えば犯人はこれである:
- xhr.setRequestHeader('X_CSRF_TOKEN', token); + xhr.setRequestHeader('X-CSRF-TOKEN', token);
こんなHTTPヘッダ、nginxが取り次いでくれるわけがない。おそらくはる~~~か昔、jQueryでAjaxをやるにあたって参考にした(いまはもう見つけられない古い)サイトからのコピペが原因だ。まぁ、HTTPヘッダなのに「_」区切りになってる時点で気づくべきだったのだ。自分が悪い。
これがなんで今まで動いていたかというと、まず(これは想像だけど)Herokuはこの手のおかしなHTTPヘッダもアプリまでちゃんと運んでくれている。で、さらに、Rack::Csrfにこんなコードがある:
def self.rackified_header "HTTP_#{@@header.gsub('-', '_').upcase}" end
このミドルウェアでは内部的に「_」を区切りに使うので、HTTPヘッダの区切りを強制的に「-」から「_」に変えているんだな。で、結果として誤ったヘッダはそのまま(変換されることなく)内部表現として扱われると。
よかれと思って書かれたコードの連鎖で本来の問題が隠れてしまうの、つらいですね……。
*1 設計が古いのでいまだにjQueryを使っている。React移植用のブランチは基本機能が動いたあたりでしばらく止まったままだ(白目)。
2018-03-11(日) [長年日記]
■ ミリシタイベント プラチナスターシアター「星屑のシンフォニア」(ミルキーウェイ)
36,000ptまで行けそうになかったので最終日は軽く流しておいたら、ちょっと危ない感じのランクになってしまった。セーフだけど。終盤伸びたのかな。怖い怖い。
コミュで天空騎士団の精鋭部隊に笑ってしまった。グリマス終了まで約1週間になって、「おれたちのミリオン」がミリシタに復活しつつある感(笑)。あと、黒井社長が美希にアプローチすると、いまだにちょっと胸騒ぎがしてしまう自分の心理が面白い(SPなんてもう10年も前の記憶である)。
B00SVMMOGC
2018-03-10(土) [長年日記]
■ 川崎 2-0 G大阪@等々力陸上競技場
今日のイベントは(恒例の)動物園だったんだけど、なぜかミッフィーとコラボしていて(動物園……?)、ユニを着たミッフィーが試合前と後に出てきてた。シュール。これがキティちゃんだったらそんなに違和感ないんだけど(笑)。
試合の方は点差以上に実力差があって、ガンバはシュートに至る攻撃すらほとんどないありさまで、いったいどうしちゃったの??? という感じだった。こっちはほぼ好きなようにやれていて、ボールを奪われてもすぐに取り返すし、パスは出せば必ず通るくらいの感覚。
見ごたえのある試合とはとうてい言えないが、楽に勝てて良かった……かなぁ。これで変に調子を崩されても困るが。