「Web API: The Good Parts」を輪読しました
2022-08-16
はじめに
以前,@kabe_239さんと「Web API: The Good Parts - O’Reilly Japan」を輪読したので感想と気になった点についてメモしていた部分を簡単に記事としてまとめておきたいと思います.
1 章 Web API とはなにか
WebAPI とは「HTTP プロトコルを利用してネットワーク越しに呼び出す API」のことです.API とは”Application Programming Interface”の略で,ソフトウェアコンポーネントの外部インタフェース,つまりは機能は分かっているけれどもその中身の動作は詳しくはわからない機能のカタマリのことをいいます.
- WebAPI を美しく設計する重要性
- 設計の美しい WebAPI は使いやすい
- 設計の美しい WebAPI は変更しやすい
- 設計の美しい WebAPI は頑強である
- 設計の美しい WebAPI は(開発者からの目線に対して)恥ずかしくない
- 対象となる開発者の数と API の設計思想
- LSUDs(large set of unknown developers):
- パブリックにドキュメントを公開し,誰でも登録して使用できるため,誰が使うか分からない
- さまざまなユースケースを想定してなるべく広く汎用的にしなければならない
- SSKDs(small set of known developers):
- 自社のスマートフォンクライアント向けの API など,API を利用する開発者が限られる
- 特定の開発者やその先に存在するエンドユーザーにとって便利で使いやすいものでなくてはならない
- LSUDs(large set of unknown developers):
2 章 エンドポイントの設計とリクエストの形式
API のエンドポイントは URI であるから,覚えやすく,どんな機能を持つ URI なのかが一目でわかるような URI にする必要があります.これは通常の WEB サービス開発における URI 設計と同様の考え方だと思われます.
- 短く入力しやすい URI
- 人間が読んで理解できる URI
- 大文字小文字が混在していない URI
- 改造しやすい(Hackable な)URI
- ドキュメントを読まなくてもその API の URI が何を行いたいのかすぐに考えることができれば,あまりドキュメントをみなくても開発に注力することが可能となる.
- サーバ側のアーキテクチャが反映されていない URI
- http://api.example.com/cgi-bin/get_user.php?user=100
- PHP で書かれていて CGI で動作していることが URI から推測することが出来,セキュリティ的にもよろしくない.
- http://api.example.com/cgi-bin/get_user.php?user=100
- ルールが統一された URI
- ユニークな情報を取得するための API に対して,クエリパラメータにユニーク ID を含めて GET するか,パスにユニーク ID を含めて GET するかのルールを統一するべきである.
Application-only authentication について書籍中に記述されていましたが,どのようなものに使用されるのかということについて理解が及ばず,たとえば Twitter の特定の人物に対するタイムライン埋め込みなどに使用されるのではないかと考えています.(例:はてなブログなどで ID やリンクを指定すると自動的に埋め込みなど?)
また,書籍中には HATEOAS というものについて記述されていたのですが,HATEOAS では,理解しにくかった URI についても rel 要素を見てどんな API の操作なのかわかるように設計することができるということなのではないかと考えています.
以下,HATEOAS 参考文献
- https://uehaj.hatenablog.com/entry/hateoas
- https://blog.tagbangers.co.jp/2019/04/05/HATEOAS
- https://www.slideshare.net/josdirksen/rest-from-get-to-hateoas
3 章「レスポンスデータの設計」
レスポンスデータのデータフォーマットについて,JSON 形式で返されるデータをよく触ることが多い気がしており,以前にも JSON 形式で帰ってくる API を利用したことが幾度かありました.
- Amazon のレスポンスデータフォーマットについて,現在は JSON 形式になっている模様.(本では XML しか対応していないと記載)
- 過去に楽天 API を利用した際のエンドポイントの書き方はクエリパラメータだった.
- JSONP について
- JSONP (JSON with padding) は,クロスサイト環境で他のオリジンから JSON データを取得するために考案された仕組みであり,パディング部分に任意のコードを埋め込めるのではないかと考えられるため,クロスオリジンなどの脆弱性を起こす可能性があると感じられた.
- JSONP に関するセキュリティの問題について以下のような記事を見つけた
- JSONP を使用したくなる場面としてどのようなものがあげられるのだろうか?
- 公式サイトの Twitter など?(例:はてなブログなどで ID やリンクを指定すると自動的に埋め込みなど?)
レスポンスデータに ID のみを含めた JSON を返すのか,また,ID を含めた個人の情報を返すのかというデータの内部構造をその API を利用する際に応じて考える必要があります.もしくは ID に付属する情報をクエリパラメータを使用し,レスポンスデータとして返す方法もあります.
そして,JSON データの返し方には階層的に返す場合とフラットに返す場合があり,階層構造で返す場合は JSON のデータサイズが大きくなってしまうため,そういった観点からこうした不要な階層化はするべきではありません.
4 章「HTTP の仕様を最大限利用する」
レスポンスヘッダで 200 を返すが,実はエラーとしてレスポンスデータが返されるような振る舞いを行っている API もあり,これはクライアントが正常に HTTP ステータスコードを認識することが出来なくなるので,HTTP ステータスコードに準ずるヘッダを返すべきです.
メールアドレスを検索する API で 410 コードを返す仕様では,メールアドレスの物理削除でも,なにかがあったこと自体は情報としてどうしても残ってしまうため,API のリクエストでメールアドレスをボディに付与し叩いてしまった際に 410 が出ると問題になるということから,個人情報保護などの観点から問題を指摘されます.
プロキシサーバがオリジンサーバでは変わってしまった情報を返してしまうことを防ぐ方法には以下の方法があります.
- 期限切れモデル:キャッシュの期限が切れたら再度アクセスして情報を取得する
- しばらく情報に変動がない者に対して有効である
- 検証モデル:今保持しているキャッシュが最新であるかどうか問い合わせて,更新されている場合のみ取得を行う
- 情報が常に変動する可能性がある者に対して有効である
クロスオリジンリソース共有(CORS:Cross-Origin Resource Sharing)とは,リクエスト側で Origin ヘッダにアクセス元を指定し,サーバ側で許可できる生成元であればアクセスを許可し,そうでなければ 403 エラーを返します.
セキュリティ上,どこから読まれても問題ない場合は Access-Control-Allow-Origin
ヘッダに *
を指定すると,どこからでも読み込めることを明示することができます.
また,”X-”という接頭辞について,独自に定義したものであり,付けても付いていなくても良いが,それ以降の独自ヘッダについて統一する必要があります.
5 章「設計変更をしやすい Web API を作る」
API のバージョンの指定方式についての違いなどについて,パス,クエリ,メディアタイプなどに指定することも可能となっています.それ以外にも,セマンティックバージョニングがバージョニングの方法として多く知られています.
クライアントに合わせたアプリケーション向けにインターフェースを変換するオーケストレーション層がサーバに存在します.多数のクライアントに合わせたインターフェースの乱立により,複雑になる可能性が示唆されるのではないか?と考えています.こういった場合,実装イメージが難しいのではないかと考えています.
6 章「堅牢な Web API を作る」
サーバ・クライアント間での情報の不正入手を防ぐために,WebAPI では以下のことに気を付ける必要があります.
- セッションハイジャックによりセッション情報を盗み,その人の ID でサービスを利用する
- HTTPS による HTTP 通信の暗号化により防ぐ
- 中間者攻撃による危険性もあるため,完全に安全であるとは言えない
また,ブラウザでアクセスする API における問題として,XSS,XSRF,JSON ハイジャックや,パラメータの改ざんやリクエストの再送信などにおける悪意のあるアクセスへの対策などを行う必要があります.そして,セキュリティ対策のためのヘッダやユーザーごとのアクセスを制限する必要があります.
終わりに
WebAPI とはどのようなものか,具体的に,そして WebAPI を実際に実装する際に気を付ける点などについて勉強することができ,とても良い書籍だと思いました.若干古い内容が含まれていたため,自分で新しい内容を調べつつ読み進めていくと良かったと思われました.
この本を読んだ後で,セキュリティに関して勉強不足を感じる部分があるなと感じてしまったため,「Web ブラウザセキュリティ ― Web アプリケーションの安全性を支える仕組みを整理する - 米内貴志」を読みたいと思いました.