技術的なやつ

技術的なやつ

8.3 Web API: The Good Parts 5章~6章(完)

第5章 設計変更をしやすい Web API を作る

APIはなるべく更新しない

  • APIが変わるとそれに依存するコードは期待通りの動作をしなくなる可能性が高い
  • LSUDs向けAPIでは告知が大変
  • SSKDs向けAPIではモバイルクライアントのバージョン問題
  • 自分たちの使っているアプリではユーザのキャッシュ問題

バージョン管理

  • パラメータでバージョン番号を取得する方法は微妙
    • 省略された場合の動作は「最新のバージョンで対応する」というようにはいかない
      • ユーザがバージョンについて意識していない可能性がある
  • URIのパスの中にバージョンを埋め込むのが良い
  • できるだけバージョンアップは避ける
    • たとえば数値を返していたパラメータgenderを文字列を返すようにしたい場合、genderStrを新たに設けて、後方互換性を保つ(バージョン番号の変化しない)変更のほうが良い

バージョン番号の付け方

  • 1.0.0のようにメジャー・マイナー・パッチの3つの数字で表すのが良い。
    • メジャーバージョンは後方互換性のない変更の時
    • マイナーバージョンは後方互換性のある変更の時
    • パッチバージョンはシステムのインターフェースに変更のないバグ修正の時
  • よって、APIURIに含めるバージョン番号はメジャーバージョン番号のみにするのが良い
    • また、バージョン番号を示すことを明示するため「v1」のような形式にするのが良い

提供終了

  • APIの公開が終了した時は、ステータスコード410(Gone)を返す仕様にしておく
  • 利用規約にサポート期限を明記する
    • 1年くらいが目安?最低6ヶ月
    • 下手に長い年数を記述すると、多くのAPIをメンテナンスする必要が出てくるかもしれない

第6章 堅牢な Web API を作る

サーバ・クライアント間での情報の不正取得対策

  • HTTPSにより通信を暗号化する

XSSXSRF対策

  • Content-Typeをきちんとapplication/jsonとする
  • IEのContent Sniffering対策にはX-Content-Type-Optionsnosniffとする
  • 通常のブラウザでは送信されないリクエストヘッダの有無を確認する
    • X-Requested-WithXMLHttpRequestであるか
  • データを16進数エスケープしておく
  • セッションごとにユニークなトークンを作り照合する(XSRF対策)
    • 直接APIを叩かれることを防ぐ

悪意あるユーザからのアクセス対策

  • パラメータ改竄の可能性を考え、サーバサイドでバリデーションを行う
    • 消費アイテムの個数に対してマイナスのパラメータを受け取った時、などに注意
  • リクエスト再送信対策
    • リクエスト送信時、ユニークな値を添える(Appleではreceiptと呼ばれる)
    • 同じreceiptで送られてきたリクエストは弾く

セキュリティ関係のHTTPヘッダ

  • X-Content-Type-Options
    • IEでContent Sniffing(メディアタイプの指定を無視する)の対策
    • nosniff
  • X-XSS-Protection
    • IEXSS検出ブロック機能が切られている時の対策
    • 1; mode=block
  • X-Frame-Options
    • 指定したページがフレーム内で読み込まれることを許可するか
    • deny
  • Content-Security-Policy
    • そのページのIMG・SCRIPT要素などの読み込み先としてどこを許可するか
    • default-src 'none'
  • Strict-Transport-Security
    • HTTPSでのアクセスを必須とする
    • max-age=15768000…この期間中、必ずHTTPSでアクセスする
  • Set-Cookie
    • session=hoge; Path=/; Secure; HttpOnly
    • Secure属性は、そのクッキーはHTTPSでのみサーバに送信される
    • HttpOnly属性は、そのクッキーはHTTP通信のみで使用され、JavaScript等からアクセス出来ない

大量アクセス対策

  • ユーザごとにAPIに対するレートリミット(アクセス回数制限)を設ける
    • 使用頻度の高いAPIは制限を緩くする
    • リミットリセットのタイミングは、長くとも1時間くらい
      • プログラムミス等でのうっかり大量アクセス時に、アクセス制限にかかる時間が長いとつらい
  • 制限値を超えた場合はステータスコード429(Too Many Requests)を返す
    • 新しいステータスコードで稼働中サービスでの使用例は少ない
    • Retry-Afterヘッダに、制限解除時間を示すとベター
    • JSONでもエラーメッセージを伝えた方が良い
  • レートリミットを知るためのAPIを用意する
    • それぞれのAPIに対して、remaining(残り回数)、reset(解除までの時間)、limit(単位時間当たりの制限数)など
    • APIのレスポンス時に、HTTPヘッダにレートリミット情報を付加する
      • X-RateLimit-Limit
      • X-RateLimit-Remaining
      • X-RateLimit-Reset

付録A Web API を公開する際にできること

  • APIドキュメントを提供する
    • ドキュメント制作用のサービスやツールもある
  • サンドボックスAPIを提供する
    • テスト環境
    • API仕様は本番環境と同じものにする
    • api.sandbox.example.comのようにホスト名を変える

まとめ

  • APIバージョンはv1の形式でURI中に含める
  • APIはなるべく後方互換性のあるバージョンアップに留める
  • 提供終了時の仕様やサポート期限を明記する
  • HTTPS
  • Content-Typeをきちんとapplication/jsonとする
  • セキュリティヘッダはとりあえずぶち込んでおく
  • レートリミットを設ける
    • レートリミット情報をきちんとユーザに渡す配慮も忘れずに
  • APIドキュメントをちゃんと書く
  • サンドボックスAPIも提供するとベター

感想

  • 付録BのWebAPIチェックリストが便利