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つの数字で表すのが良い。
- よって、APIのURIに含めるバージョン番号はメジャーバージョン番号のみにするのが良い
- また、バージョン番号を示すことを明示するため「v1」のような形式にするのが良い
提供終了
- APIの公開が終了した時は、ステータスコード410(Gone)を返す仕様にしておく
- 利用規約にサポート期限を明記する
- 1年くらいが目安?最低6ヶ月
- 下手に長い年数を記述すると、多くのAPIをメンテナンスする必要が出てくるかもしれない
第6章 堅牢な Web API を作る
サーバ・クライアント間での情報の不正取得対策
- HTTPSにより通信を暗号化する
XSS・XSRF対策
Content-Type
をきちんとapplication/json
とする- IEのContent Sniffering対策には
X-Content-Type-Options
をnosniff
とする - 通常のブラウザでは送信されないリクエストヘッダの有無を確認する
X-Requested-With
がXMLHttpRequest
であるか
- データを16進数エスケープしておく
- セッションごとにユニークなトークンを作り照合する(XSRF対策)
- 直接APIを叩かれることを防ぐ
悪意あるユーザからのアクセス対策
- パラメータ改竄の可能性を考え、サーバサイドでバリデーションを行う
- 消費アイテムの個数に対してマイナスのパラメータを受け取った時、などに注意
- リクエスト再送信対策
- リクエスト送信時、ユニークな値を添える(Appleではreceiptと呼ばれる)
- 同じreceiptで送られてきたリクエストは弾く
セキュリティ関係のHTTPヘッダ
X-Content-Type-Options
X-XSS-Protection
X-Frame-Options
- 指定したページがフレーム内で読み込まれることを許可するか
deny
Content-Security-Policy
- そのページのIMG・SCRIPT要素などの読み込み先としてどこを許可するか
default-src 'none'
Strict-Transport-Security
Set-Cookie
session=hoge; Path=/; Secure; HttpOnly
Secure
属性は、そのクッキーはHTTPSでのみサーバに送信されるHttpOnly
属性は、そのクッキーはHTTP通信のみで使用され、JavaScript等からアクセス出来ない
大量アクセス対策
- ユーザごとにAPIに対するレートリミット(アクセス回数制限)を設ける
- 使用頻度の高いAPIは制限を緩くする
- リミットリセットのタイミングは、長くとも1時間くらい
- プログラムミス等でのうっかり大量アクセス時に、アクセス制限にかかる時間が長いとつらい
- 制限値を超えた場合はステータスコード429(Too Many Requests)を返す
- レートリミットを知るためのAPIを用意する
付録A Web API を公開する際にできること
- APIドキュメントを提供する
- ドキュメント制作用のサービスやツールもある
- サンドボックスAPIを提供する
- テスト環境
- API仕様は本番環境と同じものにする
- api.sandbox.example.comのようにホスト名を変える
まとめ
- APIバージョンは
v1
の形式でURI中に含める - APIはなるべく後方互換性のあるバージョンアップに留める
- 提供終了時の仕様やサポート期限を明記する
- HTTPSで
Content-Type
をきちんとapplication/json
とする- セキュリティヘッダはとりあえずぶち込んでおく
- レートリミットを設ける
- レートリミット情報をきちんとユーザに渡す配慮も忘れずに
- APIドキュメントをちゃんと書く
- サンドボックスAPIも提供するとベター
感想
- 付録BのWebAPIチェックリストが便利