API概略

この章では艦これのAPIのリクエストとレスポンスの共通部分を解説します。

リクエスト

プロトコル

全て http です。 あらゆるものが丸見えです。

MitM で認証情報を取得した攻撃者は、全てのAPIを実行可能です。

HTTP メソッド

全てのAPIリクエストが POST メソッドを使っています。 POST メソッドは、リソースの作成に使われるべきメソッドで、 例えば艦娘のデータを取得するというAPIは、 艦娘というリソースに変化が起こらないので、 GET を使うべきですが、 全て POST が使われています。

認証

ログインの際に渡された api_token をパラメータに追加してユーザ特定を行います。 実はこれだけではなく、 Referer ヘッダーにflashのurlを設定する必要があり、 そのurlには api_tokenapi_starttime のパラメータが付けられています。

その他

Origin ヘッダーにAPIサーバのドメイン、 Accept-Encodinggzip, deflate, sdch の指定が必須でした。

レスポンス

形式

レスポンスは全てJSONです。 正確に言うと、

svdata={JSON文字列}

という、eval で評価すると変数 svdata に JSON のデータが格納される javascript のコードです。 たぶん svdata はグローバル変数で、APIのレスポンスに対する処理は1つのグローバル変数を共有しているのではないかと思います。

文字コード

文字コードはUTF-8で統一されていますが、APIのモノによってはなぜかBOM付きUTF-8になっていました。 レスポンスを出力してもBOMは目に見えないので、JSONを取得するための s/^svdata=// が上手く動かない理由に気づきにくく、非常に困りました。もしわざとやっているならなかなか優秀な罠です。

ソースコードの保存時に起きた問題と考えられ、開発者のエディタやその設定が共通化されていないことが想像できます。 また、ファイルの先頭バイトがレスポンスにそのまま出力されているという特徴から、 サーバの言語はphpではないかと予想しています。

ステータスコード

APIレスポンスのステータスコードは全て 200 OK です。 200 OK はリクエストが成功したことを表すステータスコードであり、 不正なリクエストや内部エラーなどでリクエストが正しく処理できない場合は、 200 OK ではなくふさわしいステータスコードを返すべきです。

ステータスコードの代わりに、JSON 内に api_result という情報があり、この値が 1 の場合はAPIは成功したとみなされます。 不正なリクエストや内部エラーなどでリクエストが成功しなかった場合、 api_result1 以外の値になり、 このときflashクライアントは猫画面を表示します。

===[column] ねこのひみつ APIリクエストの失敗理由が(たぶん)高負荷の場合などは、 同じリクエストを続けて送ると普通に成功することがあります。 しかしflashクライアントはそれを一切することなく、ただ闇雲にリロードしろと迫ってくるのです。 艦これ最大の敵と言われる妖怪猫吊るしはこのような仕組みで提督の精神を削っていくのです。

JSONデータ

APIレスポンスの主要なデータは、api_data というキーの中に入っています。 大雑把に書くとこのようなデータになっています。 Github には大量のレスポンスのサンプルがあります

{"api_result": 1,
 "api_data": {
    "api_count": 15,
    "api_page_count": 3,
    "api_list": [
       {"...."},
       {"...."},
       ...
    ], ...
  }
}

なぜか全てのキーに api_ という接頭詞が付けられており非常にデータサイズが無駄です。 レスポンスのデータサイズはそのまま通信量のサイズになり、 現代のコンピュータ環境では通信スピードが一番のボトルネックなので、 すなわちどれくらいのリクエストを処理できるかという話になります。 試しにいくつかのレスポンスから api_ の文字を抜いてみたら、データサイズが約2割削減できました。 単純に api_ を抜くだけで、通信コストや同時アクセス数、flashの負荷が約2割ほど改善されるということです。

まとめ: API改善ガイド

  • HTTPSを使う

  • HTTPメソッドとステータスコードを正しく使う

  • BOM付きUTF-8 や svdata= はコードからお里が知れるから削除する

  • データ削減を意識してレスポンスの構造を最適化する

Google先生が1バイトを削るのに心血を注いでいるように、 レスポンスを1バイト削ることは積み重なって大きな改善になります。 個別のレスポンスを見ていくと、酷いデータ構造もたくさんあり、 データ量の削減を意識してデータ構造を再設計するとかなり負荷は改善されると思います。

Last updated