この記事は
「DeNA IPプラットフォーム事業部 Advent Calendar 2017」
23日目の記事です。
#自己紹介
私はMyAnimeListというアニメ・マンガのコミュニティープラットフォームサービスのサーバーサイドエンジニアをしている @kawabex です。
tl;dr
ネット上で公開されているAPIについて、
- 取得できる情報がユーザの認可が必要な情報かどうか
- API呼び出し側のクライアントタイプ
の2軸で分類した際に、有名なAPI提供サービスはそれぞれの場合にどのような形式でAPIを提供しているのかを調べました。
APIの分類
取得したいデータの種類とAPIを呼ぶクライアントのタイプで分類してマトリックスを作ると、
public client | confidential client | |
---|---|---|
public data | ① | ② |
private data | ③ | ④ |
このようになり、4種類のパターンが考えられます。それぞれの単語の定義は後で説明します。
APIを提供している有名なサービスが、この①~④の4パターンについてどのような形式で(もしくはどのような技術を使って)APIを提供しているのか、まとめてみました。
以下にまとめた情報は2017/12/23現在のものです。
個人で調べた情報をまとめたので、もし間違っている部分があったら、教えていただけると幸いです。
この記事は随時追加・更新していきたいと思っています。
前提
OAuth2.0
ユーザの認可に基づいて安全にAPIをアプリに利用可能とするための標準仕様で、現在様々なAPIで広く用いられています。
OAuth2.0(Resource Owner Password Credentials Grant 以外)を利用すると、APIを呼ぶアプリ側にパスワードを含む認証情報が渡ってしまうことを回避できます。
この仕様についてはこれまで数多くの記事やブログで詳細な解説がされてきたので、この記事では説明しません。以下の記事を参考にして下さい。
- 一番分かりやすい OAuth の説明 - Qiita
- [OAuth 2.0 全フローの図解と動画 - Qiita] (https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f)
- RFC 6749 The OAuth 2.0 Authorization Framework
- [RFC 6749 の日本語訳] (https://openid-foundation-japan.github.io/rfc6749.ja.html)
client type
APIを呼ぶクライアントのタイプをRFC6749 section2.1に則って分類しました。
-
public client
クライアントクレデンシャルの機密性を維持することができず, かつ他の手段を使用したセキュアなクライアント認証もできないクライアント
例: iOS, Androidなどのネイテイブアプリ、デバイス上のUserAgent (例えばWebブラウザ) 上で実行されるアプリ -
confidential client
クライアントクレデンシャルの機密性を維持できるクライアント
例:Webアプリ
data type
本記事では、APIで提供している情報を個人のユーザーに関わる情報かどうかで2種類に分類しました。
-
public data
ユーザ個人に関わる情報が含まれていない、誰でも取得できる公開情報。ユーザの認可が必要ではないデータ。 -
private data
ユーザ個人に関わる情報が含まれているデータ。ユーザの認可が必要なデータ。
各サービスが提供しているAPIごとの情報
public client | confidential client | |
---|---|---|
public data | OAuth 2.0 or API key | OAuth 2.0 or API key |
private data | OAuth 2.0 Authorization Code Grant or Implicit Grant | OAuth 2.0 Authorization Code Grant |
※Googleが提供するAPIの数は膨大なので、今回の分類に当てはまらない例外がある可能性があります。
① public data × public client
Googleはpublic dataをOAuthを使わずに簡単に取得できるようにするために、API key という識別子を導入しています。
すなわち、Googleは各クライアントが持つユニークな識別子として、OAuth2.0 IDとAPI keyの2種類を提供していることになります。
参考:Credentials, access, security, and identity - Google API Console Help
例1: Google Sheets API Authorize Requests
例2: Google Maps API Get API Key
② public data × confidential client
①に同じ。
調べた限り、public dataの提供方法に関しては、client type の違いによる差異は無いようです。
③ private data × public client
- UserAgentアプリ(例: webブラウザ上で動くJavaScriptアプリ)の場合
Implicit Grantを採用しています。
https://developers.google.com/identity/protocols/OAuth2UserAgent - Nativeアプリの場合(例: Android, Chrome, iOSアプリ)
Authorization Code Grantを採用しています。
https://developers.google.com/identity/protocols/OAuth2InstalledApp
④ private data × confidential client
Authorization Code Grantを採用しています。
https://developers.google.com/identity/protocols/OAuth2WebServer
public client | confidential client | |
---|---|---|
public data | OAuth 2.0 Client Credentials Grant | OAuth 2.0 Client Credentials Grant |
private data | OAuth 1.0a | OAuth 1.0a |
① public data × public client
OAuth 1.0aを利用しているTwitterですが、public dataを取得するためのAPIのみ、OAuth 2.0 Client Credential Grantを採用しています。
https://developer.twitter.com/en/docs/basics/authentication/overview/application-only
The client credentials grant type MUST only be used by confidential clients.
と記載されているので、このパターンはRFC6749からは外れていることになります。これは、Twitterが基本的にOAuth1.0aを採用していることもあり、利便性を考えた結果だと思われます。
② public data × confidential client
OAuth 2.0 Client Credential Grantを採用しています。
③ private data × public client
Twitter は他の主要なサービスとは違い、OAuth 1.0aを利用しています。
https://developer.twitter.com/en/docs/basics/authentication/overview/oauth
④ private data × confidential client
クライアントタイプによって違いは無く、③と同じです。
調査中
public client | confidential client | |
---|---|---|
public data | OAuth 2.0 Custom Grant | OAuth 2.0 Client Credentials Grant |
private data | OAuth 2.0 Implicit Grant | OAuth 2.0 Authorization Code Grant |
① public data × public client
この組み合わせの為に、
grant_type=https://oauth.reddit.com/grants/installed_client
というOAuth 2.0 Extension grantsに則ったカスタムグラントを提供しています。
https://github.com/reddit/reddit/wiki/OAuth2#application-only-oauth
このカスタムグラントにより、OAuth2.0の枠組みの中で出来る限りのクライアント特定を行った上で公開情報を提供しています。
② public data × confidential client
Client Credential Grantを採用しています。
https://github.com/reddit/reddit/wiki/OAuth2#application-only-oauth
③ private data × public client
Implicit Grantを採用しています。
https://github.com/reddit/reddit/wiki/OAuth2#authorization-implicit-grant-flow
④ private data × confidential client
Authorization Code Grantを採用しています。
https://github.com/reddit/reddit/wiki/OAuth2#token-retrieval-code-flow
GitHub
public client | confidential client | |
---|---|---|
public data | 特に制限なし | 特に制限なし |
private data | OAuth 2.0 Authorization Code Grant or カスタムフロー | OAuth 2.0 Authorization Code Grant |
① public data × public client
クライアント単位での制限はかけていないようです。
https://developer.github.com/v3/guides/getting-started/#authentication
IP単位でのレートリミットは存在するようです。
② public data × confidential client
①に同じです。
③ private data × public client
Third party applications that rely on GitHub for authentication should not ask for or collect GitHub credentials. Instead, they should use the OAuth web flow.
と記載されているように、OAuth web flowを利用することが推奨されています。GitHubはImplicit Grant flowを提供していないので、結果的にAuthorization Code Grantフローの利用が推奨されてることになります。
- その他の場合
ユーザ名とパスワード(もしくはユーザ名とpersonal access token)のbasic認証により取得したアクセストークンを用いるフローが提供されています。
https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/#non-web-application-flow
このフローはOAuth 2.0 Extension grantsには則っていないGitHub独自のフローです。
④ private data × confidential client
Authorization Code Grantを採用しています。
https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/#web-application-flow
public client | confidential client | |
---|---|---|
public data | - | - |
private data | OAuth 2.0 Implicit Grant | OAuth 2.0 Authorization Code Grant |
① public data × public client
ユーザーの認可が必要ない情報を取得するAPIは提供していません。
The Instagram API requires an access_token from authenticated users for each endpoint. We no longer support making requests using just the client_id.
② public data × confidential client
①に同じです。
③ private data × public client
Implicit Grantを採用しています。
https://www.instagram.com/developer/authentication/
"Client-Side (Implicit) Authentication"の章
④ private data × confidential client
Authorization Code Grantを採用しています。
https://www.instagram.com/developer/authentication/
"Server-side (Explicit) Flow"の章
まとめ
想像以上に各サービスのAPI提供方法が異なっている印象を持ちました。ネイティブアプリ(今回の分類で言うと public client)の開発が盛んになってきた今、特に認証・認可周りはprivate clientへのAPI提供も強く意識しながらAPIを作っていく必要があると思いました。
明日24日は@m2mtu さんがGraphQLについて話してくれます。お楽しみに!