GoogleやTwitterなどで公開されているWeb APIを、ユーザのパスワードを預かることなく呼び出すことのできるOAuthというのを試してみました。 当初はOAuthの仕様を見ながらフルスクラッチで作ろうとしたのですが、よく考えたら私は英語が読めないのでした。1から作るのは諦めて公開されているrubyのライブラリを使うことにしました。
まずはサイトの登録
WebアプリケーションからGoogleのOAuth認証を使う場合、サイトの登録をしないといけません。登録は以下のURLから行います。 https://www.google.com/accounts/ManageDomains
この登録はドメイン単位で行われるので自分のドメインを持っていないと話にならないようです。なんてこったい。 しかし我々にはGoogle App Engineがついていました。ダメもとでsyttru.appspot.comを登録してみたら無事に登録完了。所有権を確認するためのメタタグをトップページに埋め込んで登録と確認が無事に完了しました。 サイトを登録するとOAuthで使うためのキーと秘密文字列が発行されます。これがないとOAuthリクエストができないので大事にメモしておきます。
コンシューマの作成
ここからプログラムに入ります。 全体のコードは最後の方に貼っておきますので気の短い方はそちらを御覧下さい。 まずはコンシューマの生成。
consumer = OAuth::Consumer.new key, secret, {
:signature_method => 'HMAC-SHA1',
:site => 'https://www.google.com',
:request_token_path => '/accounts/OAuthGetRequestToken',
:authorize_path => '/accounts/OAuthAuthorizeToken',
:access_token_path => '/accounts/OAuthGetAccessToken',
}
OAuth::Consumerクラスのコンストラクタに発行されたキーと秘密文字列を渡します。三つ目の引数は各種オプションです。 signarute_method コンシューマからGoogleへのリクエストに署名をするための方式を指定します。OAuthの仕様では「PLAINTEXT」「HMAC-SHA1」「RSA-SHA1」の三つが定義されていますが、GoogleはPLAINTEXTをサポートしていません。今回はHMAC-SHA1方式で署名します。 このリクエストの署名をするときにさっきの秘密文字列を使います。リクエストメソッド・URL・リクエストパラメータの3つのデータを、Googleとコンシューマの間だけで共有している秘密文字列を使って変換して署名することによって、他のコンシューマがリクエストを偽造することを防止できるわけです。 この辺を自前で実装しようとして苦労しました。まず英語が読めないので仕様がよくわからない上に署名というものがなんだかよくわかっていなかったので実装できるわけがなかったです。でも署名について理解が深まったからこれでいいのだ。 site request_token_path authorize_path access_token_path サービスプロバイダのドメインと各種URLです。 コンシューマがOAuthを通して認証をクリアするまで、Googleに対して全部で三回リクエストを発行しないといけません。これらリクエストのURLを設定しています。
リクエストトークンの取得
request_token = consumer.get_request_token(
{
:oauth_callback => "http://syttru.appspot.com/"
},
:scope => 'https://www.google.com/analytics/feeds/'
)
コンシューマから以下のURLにリクエストを送ってリクエストトークンを取得します。
https://www.google.com/accounts/OAuthGetRequestToken ここで取得したトークンはコンシューマが一方的に取得したもので、まだユーザーの認証がされていません。このリクエストをユーザーに認証してもらう必要があります。 oauth_callback ユーザーによる認証はGoogleとユーザーの間で行われます。認証が終わった後でGoogleがリクエストをリダイレクトする先のURLをここで指定します。 scope 2つめの引数でリクエストに追加するパラメータを指定しています。scopeパラメータはコンシューマにアクセス許可を与えるGoogleのサービスを指定します。使用できるscopeの一覧は以下のページにまとめられています。 http://code.google.com/intl/ja/apis/gdata/faq.html#AuthScopes
ユーザーによる認証とアクセス許可
puts request_token.authorize_url
ユーザーによる認証を行うために認証用のURLをユーザーに示す必要があります。実際のWebアプリケーションでは認証用のURLにリダイレクトさせて、認証をしてもらうことになります。 ブラウザで上のURLを開くとGoogleのアカウント画面が開き、コンシューマがGoogleのサービスにアクセスすることを許可するか尋ねられます。 ユーザーが許可するとGoogleは上で指定したoauth_callbackのURLにリクエストをリダイレクトし、その際にverifierという秘密の文字列を発行してリクエストパラメータに付与します。
アクセストークンの取得
上のやりとりでユーザーがコンシューマに対してGoogleのサービスにアクセスする許可を与えました。その許可を証明するverifierがコンシューマにリクエストパラメータとして渡されるので、コンシューマはこれを使ってGoogleからアクセストークンを取得します。
access_token = request_token.get_access_token(
:oauth_verifier => oauth_verifier
)
以降、コンシューマはこのアクセストークンを使うことで、Googleのサービスにユーザーのアカウントでアクセスできるようになります。
サービスにアクセス
サービスにアクセスするには上で取得したアクセストークンを使います。
resp = access_token.get('/analytics/feeds/accounts/default')
上の例を実行すると、ユーザーのアカウントでGoogle Analytics Data Export APIにアクセスしてユーザのデータを取得したりすることができます。
思ったこと
まとめるとこんな感じ。
ユーザとコンシューマとサービスプロバイダが入り乱れて三人でくんずほぐれつする様子はOpenIDと似ています。 GoogleやYahoo、Twitterといった大きなサービスがOAuthを提供しているのでいろいろと試してみようと思います。
ソースコード
require 'rubygems'
require 'oauth'
require 'oauth/consumer'
key = '******************'
secret = '************************'
begin
# keyとsecretを指定してコンシューマを生成
consumer = OAuth::Consumer.new key, secret, {
:signature_method => 'HMAC-SHA1',
:site => 'https://www.google.com',
:request_token_path => '/accounts/OAuthGetRequestToken',
:authorize_path => '/accounts/OAuthAuthorizeToken',
:access_token_path => '/accounts/OAuthGetAccessToken',
}
# リクエストトークンを取得
request_token = consumer.get_request_token(
{
:oauth_callback => "http://syttru.appspot.com/"
},
:scope => 'https://www.google.com/analytics/feeds/'
)
# サービスプロバイダの認証画面URL
puts request_token.authorize_url
print "Enter oauth_verifier:"
oauth_verifier = STDIN.gets.gsub(/\n/, "")
# ユーザがアクセスを許可したことを証明するverifierを持ってアクセストークンをもらいに行く
access_token = request_token.get_access_token(
:oauth_verifier => oauth_verifier
)
# サービスにアクセス
resp = access_token.get('/analytics/feeds/accounts/default')
puts resp
rescue OAuth::Unauthorized => error
puts error.to_s
puts error.request
end
Trackback URL for this post:http://blog.smartnetwork.co.jp/staff/trackback/46
はー。久しぶりに書くな。 Google カレンダー APIからデータを取得する機会があったので、忘れないようにメモ。 ClientLoginで簡単にやろうかと思ったけど結局OAuthを使った。 AuthSubはドキュ...
|
|||






レビトラ 販売