Edited at

「クライアントタイプ」と「認可情報の有無」の2軸で有名APIを分類して調べてみた

More than 1 year has passed since last update.

この記事は

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を呼ぶアプリ側にパスワードを含む認証情報が渡ってしまうことを回避できます。

この仕様についてはこれまで数多くの記事やブログで詳細な解説がされてきたので、この記事では説明しません。以下の記事を参考にして下さい。


client type

APIを呼ぶクライアントのタイプをRFC6749 section2.1に則って分類しました。


  • public client

    クライアントクレデンシャルの機密性を維持することができず, かつ他の手段を使用したセキュアなクライアント認証もできないクライアント

    例: iOS, Androidなどのネイテイブアプリ、デバイス上のUserAgent (例えばWebブラウザ) 上で実行されるアプリ


  • confidential client

    クライアントクレデンシャルの機密性を維持できるクライアント

    例:Webアプリ



data type

本記事では、APIで提供している情報を個人のユーザーに関わる情報かどうかで2種類に分類しました。


  • public data

    ユーザ個人に関わる情報が含まれていない、誰でも取得できる公開情報。ユーザの認可が必要ではないデータ。


  • private data

    ユーザ個人に関わる情報が含まれているデータ。ユーザの認可が必要なデータ。



各サービスが提供しているAPIごとの情報


Google

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


④ private data × confidential client

Authorization Code Grantを採用しています。

https://developers.google.com/identity/protocols/OAuth2WebServer


Twitter

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

RFC6749の仕様によると


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

クライアントタイプによって違いは無く、③と同じです。


Facebook

調査中


Reddit

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フローの利用が推奨されてることになります。


④ private data × confidential client

Authorization Code Grantを採用しています。

https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/#web-application-flow


Instagram

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.


https://www.instagram.com/developer/endpoints/


② 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について話してくれます。お楽しみに!