8 月 06 2008

Data AvailabilityでOAuthを試す

Published by えーじ under OAuth

前エントリでの予告通り、実際にサーバーサイドでコードを書き、MySpaceのData Availabilityを使ってOAuthを試してみます。Data Availabilityという名前は大げさに聞こえるかもしれませんが、実際はOpenSocial RESTful APIです。ちなみにData AvailabilityではまだJSON形式のみのサポートで、AtomPubには対応していません(しかも404が返ってくる。これに相当ハマった○| ̄|_)。

今回はOAuthを使って認証・認可を取得し、Data Availability APIを叩くところまでを解説します。

下準備

まずはサンドボックス環境にMySpaceにアプリを作ってください。細かい手順が分からない方はこの辺を参考にしてください。

MySpaceではガジェットアプリも外部アプリも同じように扱われるようです。

Edit Detailsを開くと、アプリケーションの詳細設定を編集することができます。

ここでOAuthの利用に必要なものを思い出してください。まずはコンシューマキー(consumer_key)とコンシューマシークレット(consumer_secret)です。

MySpaceの場合、アプリケーションを登録した段階でこれら2つが発行されます。コンシューマキーについては好きなものに変更できますが、ここではアプリケーションのガジェットXMLぽいURLにしてみました。後で必要になりますので、どこかにコピペっておきましょう。

次に、同じページの下の方にExternal Site Settingsという項目があります。これがData Availabilityの肝です。

  • Use External Domainにチェックを入れる
  • External URLにMySpaceからの誘導先URLを入力
  • External Domainに実際に外部アプリを置くサーバーのドメインを入力
  • 利用規約を読んで同意

これで準備オッケー。

OAuthを実装する

今回試すのは上図の外部サービス、つまりコンシューマに当たる部分です。サービスプロバイダに当たるのはMySpace。ゼロから実装してもよいのですが、せっかく便利なライブラリがありますので、これのPHP版を使って試してみます。また、署名方式はHMAC-SHA1を使います。

OAuthのフローは下記の通り。この辺りを読んで仕様を理解しておく事をお勧めします。

  1. リクエストトークンを取得
  2. ユーザー認証
  3. アクセストークンを取得
  4. リソースにアクセス

リクエストトークンを取得

必要なライブラリをインクルードします。

require_once 'oauth/OAuth.php';
require_once 'oauth/OAuth_TestServer.php';

各種変数をセットしておきましょう。先程メモったconsumer_keyconsumer_secretはここで使います。リクエストトークンを取得するためのエンドポイントはMySpaceのドキュメントに記載されています。

$consumer['key'] = 'http://devlab.agektmr.com/MyOpenSpace/DataAvailabilityExample';
$consumer['secret'] = '************';
$endpoint = 'http://api.myspace.com/request_token';

署名のロジックはめんどくさいのでライブラリにお任せ。

$server = new TestOAuthServer(new MockOAuthDataStore());
$server->add_signature_method(new OAuthSignatureMethod_HMAC_SHA1());

$sig_methods = $server->get_signature_methods();
$sig_method = $sig_methods['HMAC-SHA1'];

$consumer = new OAuthConsumer($consumer['key'], $consumer['secret'], NULL);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL, "GET", $endpoint, null);
$request->sign_request($sig_method, $consumer, NULL);

$req = curl_init($request);
curl_setopt($req, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($req);

ここまでのコードで$resultにリクエストトークンが返ってくることになります。URLのquery部と同じ形式で返ってきますので、必要に応じてパースしましょう。

parse_str($result, $tmp);

これで、oauth_tokenoauth_token_secretが取得できたはずです。

認証

次にユーザーに認証を行ってもらいます。エンドポイントはhttp://api.myspace.com/authorizeで行います。その際、先程取得したoauth_tokenoauth_callbackをパラメータとして付属します。oauth_callbackは認証後に呼び出されるページのURL。

$callback_url = 'http://devlab.agektmr.com/MyOpenSpace/access.php';
$auth_url = 'http://api.myspace.com/authorize?oauth_token='.urlencode($tokens['oauth_token']).
    '&oauth_callback='.urlencode($callback_url);

アクセストークンを取得

先程指定したoauth_callbackのURLにoauth_tokenをパラメータとして付属してリダイレクトされてきます。これはこのoauth_tokenが認証済みであることを示しており、アクセストークンへの交換が可能となります。

$consumer = new OAuthConsumer($consumer['key'], $consumer['secret'], NULL);
$tokener  = new OAuthConsumer($tokens['oauth_token'], $tokens['oauth_token_secret']);
$access = OAuthRequest::from_consumer_and_token($consumer, $tokener, "GET", $endpoint, null);
$access->sign_request($sig_method, $consumer, $tokener);

$req = curl_init($access);
curl_setopt($req, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($req);

コードはリクエストトークン取得の際とあまり変わりありません。これでアクセストークンのoauth_tokenoauth_token_secretが返っきたら準備オッケー。

RESTful APIを叩く

ここまでに取得したconsumer_keyconsumer_secretoauth_tokenoauth_token_secretを使って署名したOAuthリクエストをRESTful APIに投げることにより、友達リストなどのデータ取得が可能になります。

$consumer = new OAuthConsumer($consumer['key'], $consumer['secret'], NULL);
$tokener  = new OAuthConsumer($tokens['oauth_token'], $tokens['oauth_token_secret']);
$resource = OAuthRequest::from_consumer_and_token($consumer, $tokener, "GET", $endpoint, array('format'=>'JSON'));
$resource->sign_request($sig_method, $consumer, $tokener);

$req = curl_init($resource);
curl_setopt($req, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($req);

これでエンドポイント($endpoint)を取得したいリソースのURLにすればOK。レスポンスボディにJSON形式でデータが返ってきます。

サンプルアプリ

上記コードを使って一連の流れを見ながら動作を確認できるサンプルを用意しました。どういうリクエストを投げるのか参考になると思います。

実際に動作するサンプルはコチラ

8 月 02 2008

OpenSocialのOAuthまとめ

Published by えーじ under OAuth, OpenSocial

OpenSocialでは、コンテナが外部サーバーとの通信を行う際、または外部サーバーがコンテナと通信を行う際、OAuthを使用して認可を行います。今回はOpenSocialにおけるOAuthについて、現段階でのまとめを書いてみます。

OAuthって何だったっけ?

OAuthはユーザーコンシューマサービスプロバイダの3者間でデータのやり取りを行うとした場合、ユーザーがコンシューマにクレデンシャル(IDやパスワード)を渡すことなく、ユーザーが所有するサービスプロバイダ上のリソースにコンシューマをアクセスさせるためのものです。

例えばユーザーGoogle(サービスプロバイダ)アドレス帳(リソース)MySpace(コンシューマ)上で利用するシーンを思い浮かべてください。OAuthがなければ、MySpaceにGoogleのIDとパスワードを預けなければならなかったものが、OAuthを使うことで、ユーザーが直接Googleと認証のやりとりを行い、MySpaceにGoogleのID/パスワードを渡すことなく、アドレス帳のデータをMySpaceに渡すことができるようになります。

2種類のOAuth

さて、そんな便利なOAuthですが、OpenSocialで利用されるものには2種類あります。

OAuth Core

OAuth Coreでは、先程説明したように、ユーザーコンシューマサービスプロバイダの3者間でやり取りを行います。ベーシックなものですので、詳細についてはこの辺りを参考にしてください。

OAuth Consumer Request

一方OAuth Consumer Requestは、OAuthの仕様からユーザー認証部分を除き、コンシューマとサービスプロバイダのやり取りにフォーカスした仕様で、一般に”two-legged OAuth“と呼ばれます。これはコンシューマとサービスプロバイダの信頼関係だけで、ユーザーによる認証を伴わない仕様のため、コンシューマがサービスプロバイダからパブリックな情報を取得したい場合に利用するケースが想定されます。

ちなみにOpenSocial v0.7ではOAuth Coreの利用は仕様に含まれておらず、このtwo-legged OAuthを利用することになっています。OAuth Coreが利用できるのはOpenSocial v0.8以降での話になります(もちろん、two-legged OAuthも利用できます)。

OpenSocialにおけるOAuth利用パターン

OpenSocialでOAuthを利用する形態として、さらに2通りが考えられます。

ガジェットが外部サーバーとやり取りを行うOutbound OAuth

ここでは仮にOutbound OAuthと呼びます。type=”html”で作られたガジェットが、SNSコンテナをプロキシとしてコンシューマの役割を果たし、サービスプロバイダとなる外部サーバーとmakeRequestで通信を行うケースです。

外部サーバーがコンテナとやり取りを行うInbound OAuth

ここでは仮にInbound OAuthと呼びます。コンシューマとなる外部サーバーがサービスプロバイダであるSNSコンテナのRESTful APIを叩くケースです。type=”url”のガジェットが外部サーバーを通してSNSコンテナのRESTful APIを叩くケースもこれに該当します。

OAuthの利用に必要なもの

OAuthの利用には前提条件がいくつか存在します。細かい仕様は別途調べていただくとして、事前に必要な条件が下記になります。

  • コンシューマが、サービスプロバイダの発行する以下を事前に知っていること。
    • コンシューマキー(consumer_key)
    • コンシューマシークレット(consumer_secret)
  • コンシューマが、サービスプロバイダとOAuthのやり取りを行う以下3つのURLを知っていること
    • サービスプロバイダのリクエストトークンURL
    • サービスプロバイダのアクセストークンURL
    • サービスプロバイダの認証URL

OAuth利用パターンごとにどのようにしてこの条件をクリアするかを検証してみます。

Outbound OAuthのケース

ガジェットが外部サーバーとやり取りを行うケースですので、まずはガジェット開発者がSNSコンテナにコンシューマキーとコンシューマシークレットを登録します。ですが僕の知る限り、まだOutbound OAuthを実装しているSNSはありません。なので、ここでは何かしらの手段を用いて(SSLページでFormを使って投稿等)、コンシューマキーとコンシューマシークレットをコンテナに渡したものと想定してください。(今後順次、これを実現する方法は登場するものと思われます。)

次に、サービスプロバイダの各種URLを渡す必要がありますが、v0.8ではガジェットXMLで渡すよう規定されています。OAuthをModulePrefsの中に作成してください。

<oauth>
<service name="google">
<request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/" />
<access url="https://www.google.com/accounts/OAuthGetAccessToken" />
<authorization url="https://www.google.com/accounts/OAuthAuthorizeToken" />
</service>
</oauth>

OAuthは必ずしも1つのサーバーとやり取りするとは限りませんので、Serviceを追加することで複数をサポートすることができるようになっています。Service@nameで使い分けることが出来るようになっていますので、必要に応じてmakeRequestのopt_paramsに下記のパラメータを加え、サービスを指定してください。

gadgets.io.RequestParameters.OAUTH_SERVICE_NAME

サービスプロバイダとOAuthのやり取りを行うURLについては、XRDS-Simpleによって解決する方法もありますが、こちらについては別の機会にまとめてご紹介します。

Inbound OAuthのケース

外部アプリケーションがSNSコンテナのRESTful APIにアクセスする場合になります。これはまさに、FacebookのFacebook ConnectやMySpaceのData Availability、GoogleのFriendConnectに該当するもので、まだ実験的な段階にあると言えるものです。

コンシューマキーとコンシューマシークレットですが、SNSコンテナ上でアプリケーションを登録することで発行されます。それをディベロッパがメモ/コピペしてコンシューマとなるサーバーのコードに埋め込みましょう。URLについては、単純にヘルプページを見る方法と、XRDS-Simpleによるオートディスカバリを行う方法が考えられます。

まとめ

今回は大まかな話を書きましたが、次回は実際にMySpaceのData Availabilityを使ってOAuth認証を行い、データを取得するところまでを試してみたいと思います。

6 月 20 2008

FriendConnectから垣間見える未来のソーシャルウェブ

今更ですが、先日サンフランシスコで開かれたGoogle I/Oに参加してきました。

その中でも特に印象に残ったのが、PlaxoのJoseph Smarr氏によるOpenSocial, OpenID, and OAuth: Oh My!というセッション。僕が見たセッションの中ではダントツの人気で、部屋に用意された椅子はもちろん、立ち見で人が溢れ返るほどの盛況ぶり。

内容は、ソーシャルウェブの未来について。現在はOpenSocialというソーシャルグラフを所有するサービスに閉じた世界が中心となりつつありますが、少し未来のウェブはOpenSocial, OpenID, OAuth, PortableContacts等の技術によって、よりグローバルな意味でのソーシャル化が図れるようになる、というものです。

詳細はGoogle Codeにビデオとスライドがアップされていますので、ご覧ください。かなり早口ですが、大変面白い内容です。

OpenSocialとFriendConnectの持つ意味

OpenSocialにはv0.7まで、JavaScriptのAPIしか存在していませんでした。これはOpenSocialコンテナにとっては外部サービスからガジェットとしてアプリケーションを追加してもらい、そのOpenSocialコンテナが持つソーシャルグラフに閉じた形で利用されるものでした。アプリケーション開発者はOpenSocialのJavaScript APIを使い、ガジェットが置かれているコンテナサイトの友達リストを取得し、そこでアプリケーションを動かすことができます。もちろん、ガジェットを自分のサービスドメイン上でホスティングすることも可能ですが、ガジェットはコンテナ上でしか動作せず、友達リストを外部サービスとしてインポートしたりといったことも不可能で、実質的に囲い込みサービスしか生まれないものと言えたでしょう。

それがOpenSocial v0.8 + FriendConnectによって一気に世界を広げます。ユーザーはFriendConnect対応サイトを利用するに当たり、OAuthを使って自分が利用したいSNSサービスを選ぶ権利が与えられています。同時に、そのサイト上での活動内容は連携を選択したSNSサービスに戻されます。

ここでソーシャルサービスの要素を思い出してください。

  1. アイデンティティ
  2. ソーシャルグラフ(友達リスト)
  3. エントリの公開範囲の制御(プライバシー)
  4. フィード

FriendConnectはアイデンティティをOpenIDで、ソーシャルグラフをOpenSocial v0.8のRESTful APIで、エントリの公開範囲の制御をOAuthで、フィードをActivity Streamで解決しようとしています。

これらの意味するところを深く見つめて行くと、未来のソーシャルウェブが自ずと見えてきます。

Joseph Smarr氏(Plaxo)による未来のソーシャルウェブ論

FriendConnectのイメージをさらに深めるため、Joseph Smarr氏が、PlaxoのFriendConnect対応に際してアップしていたブログエントリをご紹介します。

Plaxo and FriendConnect are now Best Friends

Plaxoが完全にFriendConnectと連携した。FriendConnectとは、あらゆるサイトをソーシャル化する、Googleによるウィジェットベースのツールである。これにより、FriendConnectに対応していれば、どんなサイトでもPlaxoアカウントに安全に接続し、サイト上に自分の友達がいるかを確認したり、友達を招待したりといったことができるようになる。何よりも素晴らしいのは、そのサイトでの活動内容をPulseに流し込むことができるようになり、Plaxoでの友達がウェブを跨いであなたと連絡を取り合うことができ、あなたが発見した新しいサイトを知ることができる点だ。

これは本当に便利でわくわくする連携機能だ — これはユーザーが自分のアイデンティティと関係をウェブ上のどこでも利用できるようにし、新しいサイトで知人を見つけ出し、活動内容を既存の友達に共有し、よりソーシャルな発見と共有という徳の高いサイクルを生み出す、シームレスソーシャルウェブエコシステムにさらに近付いたと言える。これこそソーシャルウェブの進むべき道だ — (現在あるほとんどのサービスがそうだが)新しいソーシャルサイトを使い始める度に最初からやり直さなければならないなんてとんでもない。あなたの新しい体験全てが、他の人をも魅了すべきだ。

これはサービスがユーザーに自分の持つデータの制御を与え、オープンスタンダードを使って安全なアクセス権を提供することによってのみ成り立つ。そしてこれこそまさに、PlaxoがFriendConnectを使ってやりたかったことだ。Plaxoアカウントを接続する際、我々はOAuthを使う。そのため、Plaxoのパスワードを渡す必要もないし、後で接続を断つことも可能だ。FriendConnectを使ってあなたが活動内容をPulseに共有する際は、OpenSocial 0.8 RESTful Activities APIを利用する。オープンスタンダードではない連携はアドレス帳APIのみであり、我々はこのスタンダードについても取り組みを開始している。我々はアイデンティティプロバイダとして、ソーシャルグラフプロバイダとして、そしてコンテンツアグリゲータとしての役割を果たしていると強く信じている — つまり、我々はユーザーが自身のデータと関係性をウェブ上のどこにでも持ち回り、どこからでも共有できるようにしている — これはユーザーにとっても、Plaxoにとっても、ウェブ全体にとっても有益なことだ。だが、まだこの取り組みは始まったばかり — FriendConnect対応サイトから活動内容を共有する際、家族や友達、仕事関係など、共有相手をより細かい粒度で制御するなどの、更なる拡張を楽しみにしていて欲しい。

下のスクリーンショットはPlaxoとGoogle FriendConnectの連携したものだ — FriendConnectを利用しているサイトでも体験してもらうことができる。

画像は実際のページをご覧下さい。

まとめ

ガジェットコンテナとしてのOpenSocialには正直、懐疑的な部分があったのですが、FriendConnectの描く未来を想像し、またわくわくしています。今後もこの辺りの動向を追って行きます。

追記

似たような話題に触れた記事を見つけたので追記し、トラバっておく。(失敗したので断念○| ̄|_)

グーグルが見たソーシャルネットワーキング–その3つの傾向:スペシャルレポート - CNET Japan

4 月 19 2008

MySpaceのRESTful APIでOAuth認証を試してみる

Published by えーじ under OAuth

MySpaceで公開されているMDP(MySpace Developer Platform)には、OpenSocialだけでなく独自のRESTful APIも含まれており、これを使うことでサーバーサイドにアプリケーションを作ることもできるようになっています。今回は、MDPのRESTful APIのOAuth認証にフォーカスを当ててみます。

OpenSocial/MDPのOAuthについて

OAuthとは、ユーザーとユーザーが利用したいサービス(以後サービスプロバイダ)を仲介するOpenSocial等のコンテナ(以後コンシューマ)が、サービスプロバイダの認証情報を知ることなくAPIを操ることを可能にする、認可のためのプロトコルです。

例えばユーザーがコンシューマ上でサービスプロバイダのアプリを利用しようとすると、サービスプロバイダのドメイン上にある認証画面にリダイレクトされ、ユーザーが許可をし、そこではじめて、コンシューマがサービスプロバイダのAPIを利用可能になる、という使い方が想定されています。

しかし、現在のところOpenSocialで規定されているOAuthはフルスペックではありません。ユーザーがサービスプロバイダの認証画面にリダイレクトされたり、コンシューマとサービスプロバイダがトークンを交換したりといった仕様は想定されていないのです。

これはOpenSocialガジェットがJavaScriptで動作しているためトークンを管理できない、等の理由があるようですが、MySpace独自のRESTful APIでも条件は同じようで、コンシューマキーとコンシューマシークレットがあれば、トークンなしでOAuth認証を行うことができます。

※OAuthの詳しい仕様に関してはこの辺りを参考にしてください。

アプリケーションプロフィールを作る

まずはMySpaceでアプリケーションを作る準備をします。

MySpaceでアプリケーションを作るためには、ユーザーアカウントとアプリケーションのプロフィールアカウントが必要です。下記のサイトにスクリーンショット付きで解説がありますので、参考にしてください。

MySpaceアプリケーションを作ろう - ラーニング人生。

OAuth認証の準備

アプリケーションプロフィールが作れたら、XMLやJavaScriptのコードは不要です。今回の目的はRESTful APIの認証を試すところにありますので、画面左のMy Appsをクリックし、作成したアプリケーションプロフィールのEdit Detailsをクリックしてください。

画面下部にOAuth Consumer KeyとOAuth Consumer Secretという部分があります。RESTful APIにアクセスするには、これらが必要になりますので、メモ帳などにコピペしておいてください。OAuth Consumer Keyは任意に変更できますので、変更してもよいかもしれません(保存は忘れずに)。 

OAuth Toolで認証してみる

OAuthではコンシューマキーとNonce、Timestampなどから署名(Signature)を作って認証を行います。署名の作り方は複雑なので、今回はMDPで提供されているOAuth Toolを使って試してみます。

画面右にある項目を埋めていきます。

  • Server: サーバーURL。RFC3986で言うschemeとauthorityに当たります。ここではhttp://api.myspace.comとします。
  • ResourceURL: サーバーURL以降のパス。RFC3986で言うpathに当たります。queryとfragmentは含みません。ここは/users/{user_id}/friendsとして、user_idにはあなたのユーザーIDを入力してください。他の利用可能なエンドポイントはここに記載されています。
  • Request Method: HTTPメソッド。GETとします。
  • Consumer Key: OAuthのコンシューマキー。先程メモったConsumer Keyを入力してください。
  • Consumer Secret: OAuthのコンシューマシークレット。先程メモったConsumer Keyを入力してください。
  • OAuth Token: トークン。正式なOAuthではサービスプロバイダに許可を受けてアクセストークンと交換し、初めて認可されます。今回は空の状態にしてください。
  • OAuth Token Secret: トークンシークレット。正式なOAuthでトークンの交換に必要になります。今回は空の状態にしてください。
  • OAuth TimeStamp: TimeStamp。UNIXタイムで現在時刻を入力します。今回は空の状態にしてください。
  • OAuth Nonce: Nonce。何でもよいですが、毎回必ず違う値を送る必要があります。今回は空の状態にしてください。
  • Signature Method: 署名方式。HMAC-SHA1を選択。
  • Version: OAuthのバージョン。1.0とします。
  • OAuth Mode: OAuthモード。Authorization Headerとしてください。
  • Query options: OAuth Toolの使い方。Generate URI and Submitとしてください。

これでOK。executeをクリックします。

Response Bodyにどんな表示が返ってきたでしょうか。自分の友達リストが返ってきていれば成功です。Resource URLの最後に”.json”を付け加えると、結果をJSON形式にすることもできます。

まとめ

実はこのやり方のOAuthは、外部サーバーからコンテナであるMySpaceに対してリクエストを投げる場合だけでなく、OpenSocialのmakeRequestで、コンテナのプロキシを介して外部サーバーに送られるリクエストでも同じやり方が利用されます。その際は当然、自分で用意するサーバーの受け口がOAuthをサポートしている必要があります。

気になるのは、やはりトークンの交換や、サービスプロバイダ側に認証を行わせる部分が省かれていること。OpenSocialとOAuthは非常に相性が良いと思っていたのですが、認証が出来ないとなると、サービスプロバイダが持つUserIDとコンテナのUserIDを紐付けたりといったことができないことになります。僕が仕様を勘違いしているだけなのか、今後OAuthにもちゃんと対応して行くのか。

makeRequestを使った外部サーバーとのデータ交換については、また別の機会に解説します。

※API(OAuth Tool?)が不安定なようで、お昼はうまくいったのにこの記事を書いている時点では、なぜかNot Foundが返ってきてしまいました・・・