2009年10月4日日曜日

各種WebサービスのAPI認証方法を調べてみた

自分でWeb サービスを作る際に、APIの認証ってどうやって作ればよいのだろうと思い立ち、各種Web サービスのAPIの認証方法を調べてみました。


■Google
参考にしたページはこちら。
http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI
認証方法
ユーザーIDおよびパスワードを元に、Cookieを生成
認証時のAPI通信
HTTPS POST
認証URL
https://www.google.com/accounts/ClientLogin
認証後のAPI通信
HTTP GET/POST, HTTPS GET/POST
トークン送出方法
HTTPリクエストヘッダのCookie属性に「SID」を含める
Cookieを使う方法ですので、Webブラウザを用いるWebアプリケーションに対する認証の場合は非常に簡単ですが、クライアントアプリケーションの場合は、認証URLのレスポンスを元にSIDを保存し、HTTPリクエストヘッダのCookie属性にSIDを追加する処理を自分で行う必要があるため、ちょっとだけ面倒です。それでもシンプルで分かりやすい方法だと思います。


■Remember the Milk(RTM)
参考にしたページはこちら。
http://www.rememberthemilk.com/services/api/authentication.rtm
http://www.rememberthemilk.com/services/api/methods/rtm.auth.getFrob.rtm
認証方法
APIキー、開発者とサーバー間の共通鍵、使い捨てセッションの3つを元に、セッションIDを生成
認証時のAPI通信
HTTP GET
認証URL1(使い捨てセッションの取得)
http://api.rememberthemilk.com/services/rest/?method=rtm.auth.getFrob&api_key=abc123
認証URL2(本認証)
http://www.rememberthemilk.com/services/auth/?api_key=abc123&perms=delete&frob=123456&api_sig=zxy987
認証URL2(認証済みセッションIDの取得)
http://api.rememberthemilk.com/services/rest/?method=rtm.auth.getToken&api_key=abc123&frob=123456

認証後のAPI通信
HTTP GET
トークン送出方法
HTTPパラメータに「auth_token」を含める
Webアプリケーションだけではなくクライアントアプリケーションへの対応を行っているためか、先ほどのGoogleのAPIと比べて格段に難しくなります。その代わり、HTTPS POSTを用いなくても、HTTP GETのみで認証を行うことが出来ます。こういうのをRESTって言うんでしょうか?正直良く分からず。
以下、クライアントアプリケーションでの認証手順。

1.APIキー申請をすると、以下の2つの値がもらえる
api_key・・・開発者がサーバーからもらえる公開鍵。公開鍵なので外に漏れても良い。
shared secret・・・開発者とサーバーが持つ共通鍵。絶対に外に漏れてはならない。

2.api_keyを元に、使い捨てセッションを生成する
frob・・・使い捨てセッション。以降、認証手続きの間のみ利用する。
frobの意味についてはhttp://en.wikipedia.org/wiki/Frobを参照。

3.shared secretと認証URLのリクエストパラメータを元に、api_sigを生成する。
認証URLには以下の3つのリクエストパラメータがつきます。
api_key=abc123&perms=delete&frob=123456
これを記号を抜いて結合して、
api_keyabc123permsdeletefrob123456

先頭にshared secretをつけて、
BANANASapi_keyabc123permsdeletefrob123456

md5 hash値を計算します。計算結果がapi_sigになります。
md5('BANANASapi_keyabc123permsdeletefrob123456')

4.api_key, frob, api_sigの値を元に、ユーザー認証画面を開いてIDとパスワードを入力してもらう
ここで認証URL2をユーザーにブラウザで開いてもらって、IDとパスワードを入力してもらえば認証が完了します。

5.認証が完了したセッションIDを取得する
auth_token・・・セッションID。次以降のリクエストには、全てこのauth_tokenをHTTPリクエストパラメータとして含める。


■Evernote
参考にしたページはこちら。
http://www.evernote.com/about/developer/api/evernote-api.htm#_Toc200272584
認証方法
メールアドレス、パスワード、consumerKey, consumerSecretを元に、セッションIDを生成
認証時のAPI通信
Thrift TBinaryProtocol wrapping a THttpClient transport
認証URL
https://www.evernote.com/edam/user
認証後のAPI通信
Thrift
トークン送出方法
UserStore Authentication Token?を付与する
Thriftというフレームワークが使われているようです。Thriftの実装がC, Java, PHP, Python, Perl, Rubyなどで用意されていて、クライアントはこれらの実装を用いて認証すればよいらしいです。詳細は良く分かりませんが、こちらもAPI Keyと共通鍵を利用しているため、比較的RTMの認証に近いことをしているように見えます。
ちなみに上記はクライアントアプリケーション用の認証で、Webアプリケーション用の認証にはOAuthを使用しています。OAuthについてはまた別の機会に調べます。


■Twitter
参考にしたページはこちら。
http://usy.jp/twitter/index.php?Twitter%20API
http://twitter.pbworks.com/API%20Docs#Authorization
http://watcher.moe-nifty.com/memo/2007/04/twitter_api.html
認証方法1
ユーザーID、パスワードを利用したBasic認証
認証時のAPI通信
なし
認証URL
なし
認証後のAPI通信
HTTP GET
トークン送出方法
http://username:password@twitter.com/のようにしてユーザーIDとパスワードを送出する
認証方法2
ユーザーIDおよびパスワードを元に、Cookieを生成
認証時のAPI通信
HTTP POST(HTTPSは無い?)
認証URL
http://twitter.com/login
認証後のAPI通信
HTTP GET
トークン送出方法
HTTPリクエストヘッダのCookie属性に「_twitter_session」を含める
認証方法3
OAuth
詳細については不明
以下、http://watcher.moe-nifty.com/memo/2007/04/twitter_api.htmlから転載。

public_timeline の取得等一部の API を除くほとんどの API で、認証を使用する。応答に protected なユーザに関する情報が含まれる可能性のある API は認証が必須となっている。
現在、OAuth認証とBASIC認証が使用可能。

トークンベースの認証 OAuth は、今のところベータ版であるが、将来、OAuth 認証を標準的な認証方法にする予定。
BASIC認証で使用するユーザ名はメールアドレスまたはスクリーン名のどちらでも構わない。

Webブラウザ等を経由して Twitter にログインしたときに発行される cookie を使うことで BASIC 認証の代わりにすることもできるが、公式には cookie を使っての API 実行はサポートしない。
(訳者による注記: API によっては cookie 使用時も BASIC 認証が要求されるものもある。また、BASIC認証での API 実行と cookie を利用しての API 実行では、異なる結果が返る API もある。特に、protected なユーザに関する挙動に違いが見られる。
OAuth 認証時も API の応答に cookie が含まれるが、次回 API 実行時にこの cookie をサーバーへ送り返す必要はない)。

もうこれを見るだけでばっちりでした。