Archive for the 'OAuth' Category

8月 18 2009

GadgeTweetr: The first and ultimate Twitter client on OpenSocial using OAuth

Published by Eiji under OAuth, OpenSocial

GadgeTweetr_Logo

goo Home just launched its Outbound OAuth support from today. Now, any gadget developers on goo Home can easily mash up external contents authorized using OAuth.

For demonstration purpose, I’ve developed a gadget, which I believe is the world’s first Twitter client on OpenSocial using OAuth, called “GadgeTweetr“. GadgeTweetr is simple, but powerful, even on comparing to other desktop Twitter clients.

Major features

  • OAuth Login
  • Tabs
  • Show In-Reply-To
  • Search
  • Multi-account

OAuth Login

With support of OAuth, GadgeTweetr can let users login to Twitter without giving credentials to goo Home. Just by clicking “Login” button, a new window opens with clear indication that the browser is showing page on twitter.com, users can login to Twitter safely without worrying this is phishing.

login_using_oauth

Tabs

Using OpenSocial tabset feature, GadgeTweetr provides view of various status pages like some other Twitter clients do. Timeline, Mentions, Direct Message, Favorites, etc.

tabs

Show In-Reply-To

If the status is in-reply-to someone, GadgeTweetr shows “reply to:” beside its date. Clicking it will insert source status just blow that, so that you can drill down (up?) to the original tweet.

replies

Search

You can search on Twitter. GadgeTweetr opens search result tab.

search

Multi-account

User can embed multiple copies of GadgeTweetr gadgets on goo Home’s home page with different authentications. So you have multiple Twitter accounts in one view!

multi-account

Misc features

3 views

GadgeTweetr has 3 views: home, profile and canvas. Home view provides Timeline, Mentions tabs, profile view provides its owner’s timeline, canvas view provides Timeline, Mentions, Direct Message, Favorites tabs as default.

Auto link

GadgeTweetr detects @ and # and hyper link it, as well as external link. External link will open new window. @ and # opens new tab in GadgeTweetr showing respective status.

ReTweet

By clicking ReTweet button, you can tweet copy of your favorite status message with indication of ReTweet: “RT”. Of course, you can add your comment just as you do on your own tweet.

Show profile

Clicking thumbnail of a user shows profile dialog with description of the person, numbers of friends, followers, tweets.

Follow, unfollow

On profile dialog, you can even follow or unfollow the user depending on your relationship with the user.

Summary

So, this is the “GadgeTweetr”. Sorry but this gadget only works on goo Home for now, since I don’t know any other containers which supports OAuth properly designed to deploy this kind of gadget.

However, this gadget is already supporting English and is ready to serve to other containers. Although current version is just a plain Twitter client, I’m planning to implement more SOCIAL functionality as well.

Hope this helps the evolution of social web!

View Comments add to hatena hatena.comment (12) add to del.icio.us (0) add to livedoor.clip (2) add to Yahoo!Bookmark (1) Total: 15

1月 08 2009

Footprint gadget for your FriendConnect

I developed FriendIntroducer as an experiment and was trying to understand how FriendConnect is different from ordinaly OpenSocial implementation. So this time, I’ve tried to develop a gadget which you can find FriendConnect interesting, Footprints. You know the idea if you’ve tried MyBlogLog before.

What is Footprints?

Footprints is a gadget to track visitor of you blog. Look at the gadget on bottom left of this blog. If you’re not joined or signed in, do it to check what it does.

Footprint is a pretty popular idea on japanese social networks. Once upon a time, SNS were all closed and it was difficult to find people you may know. Footprint functionality was a good tool at that time to find who’s interested in you.

Footprints1

As you could imagine, this gadget records visitor and its time. When viewed by others, timestamp will be displayed how long ago, you’ve visited. Also, you can remove your own footprint if you want. The xml is located at:

http://devlab.agektmr.com/OpenSocial/FriendConnect/Footprints.xml

Feel free to take it and use it on your blog.

View Comments add to hatena hatena.comment (6) add to del.icio.us (0) add to livedoor.clip (1) add to Yahoo!Bookmark (0) Total: 7

10月 04 2008

OAuthの署名方式を掘り下げる

Published by Eiji under OAuth

当ブログでこれまで何度かOpenSocialに絡んだOAuthについて取り上げてきましたが、MySpaceを参考にしていたため、署名方式としてHMAC-SHA1のみを対象にしてきました。しかしShindigを掘り下げる上でRSA-SHA1を避けて通ることはできず、むしろこちらについても十分な知識を得ていないとなかなか先に進めないことが分かりましたので、この機会にまとめてみます。(OpenSocialをある程度前提にしていますが、署名の話はOpenSocialに限らないものです。)

署名とは何か

ITの世界で署名とは、問い合わせ元がその人であることを証明するための手段、と言えます。OAuthだと、コンシューマがサービスプロバイダに対して、名乗っている通りの者であることを証明することを意味します。これは、「自分」もしくは「相手と自分」にしか分からないものをリクエストに付け加えて送ることで実現されます。

OAuthの仕様では、署名方式について厳密に規定していませんが、HMAC-SHA1、RSA-SHA1、PLAINTEXTの3つの署名方式を説明しています。

OAuth does not mandate a particular signature method, as each implementation can have its own unique requirements. The protocol defines three signature methods: HMAC-SHA1RSA-SHA1, and PLAINTEXT, but Service Providers are free to implement and document their own methods. Recommending any particular method is beyond the scope of this specification.

HMAC-SHA1

HMAC-SHA1を使ったOAuthでは、予めコンシューマとサービスプロバイダが、同じコンシューマキー(oauth_consumer_key)とコンシューマシークレット(oauth_consumer_secret)を持ちます。コンシューマシークレットはもちろん、秘密というくらいですから、2者以外に知られてはいけません。2者がコンシューマシークレットを共有することから、Shared Secretと呼んだりもします。

MySpaceでは、コンシューマキーをアプリケーションのURL、コンシューマシークレットをMD5らしきランダムな(?)ハッシュ文字列としていますが、コンシューマキーはディベロッパの任意で変更可能です。詳しくはこの辺りをご覧下さい。

RSA-SHA1

逆に、RSA-SHA1の方式では、コンシューマが公開鍵と秘密鍵を持ちますが、サービスプロバイダは秘密鍵を知ることはありません。コンシューマは秘密鍵で暗号化した署名を加えたリクエストを投げます。この暗号化された署名は、公開鍵でしか解くことができませんし、秘密鍵でしか作ることができないため、コンシューマが身分を証明できる、という訳です。

署名を作る際、HMAC-SHA1方式の場合、コンシューマシークレット(oauth_consumer_secret)とトークンシークレット(oauth_token_secret)を”&”で繋いだものをkeyとして利用しますが、RSA-SHA1方式の場合、秘密鍵をkeyとして使って暗号化します。そのため、コンシューマシークレットとトークンシークレットは不要です。

逆にサービスプロバイダは、公開鍵を使って署名が正当なものであることを確認します。

$publickeyid = openssl_get_publickey($cert);
$ok = openssl_verify($raw, $signature, $publickeyid);
openssl_free_key($publickeyid);

$certは公開鍵、$rawは署名の基本文字列(Signature Base String)、$signatureは署名文字列(oauth_signature)を表しています。$rawと$signatureはコンシューマからのリクエストで生成することができますが、$certについてはちょっと考察が必要です。

RSA-SHA1の公開鍵の扱い

OAuthの拡張としてOAuth Key Rotation Extensionが提案されています。これはコンシューマがサービスプロバイダにリクエストする際、公開鍵のIDをリクエストと一緒に渡すことで、サービスプロバイダに鍵をダウンロード/認識させるための仕様です。公開鍵のIDはxoauth_signature_publickeyパラメータで渡されます

OAuth Key Rotation Extensionのドラフト、OpenSocial/Gadgetの仕様書など、いくつかのドキュメントにxoauth_public_keyと記述されていますが、Shindigの実装でxoauth_signature_publickeyが使用されており、こちらが正式なものとなるようです。

ここで公開鍵のIDと言いましたが、もちろん、これだけでは公開鍵を取得することができないので、これを使ってゴニョゴニョする必要があります。

が、、、。

OpenSocial/Gadgetの仕様書には

The container should make its public key available for download at a well-known location. The location https://container-hostname/opensocial/certificates/xoauth_public_keyvalue is recommended.

と書いてあるのですが、Shindigの実装ではhttp://container-hostname/public.cerになっていたりと、仕様が一貫していません。

現実はどうしているかというと、xoauth_signature_publickeyを無視して、コンテナのドキュメントに書いてある公開鍵をコピペしてソースコードにハードコーディングしています。hi5、Orkutについては動作確認ができました。iGoogleについてはここに公開鍵が書いてありますが、動作しませんでした。

OAuthが広まって様々なコンシューマが登場するまでは、まだまだこの中途半端な状態が続くのではないでしょうか。

コンシューマは誰か

ここで勘のいい方は気付かれたと思いますが、RSA-SHA1方式の場合、署名元がOpenSocialのコンテナサイトそのものになっています。MySpaceのように、ガジェットではありません。ということは、もちろんコンシューマキー(oauth_consumer_key)もOrkutなら”orkut.com”、hi5なら”hi5.com”といった具合に、コンテナサイトを表すものが使用されます。

またこの方式の場合、どのガジェットがリクエストを投げているのかを表すため、xoauth_app_urlというパラメータが追加されます。これを提案しているのがOAuth Gadget Extensionです。

MySpaceのようにHMAC-SHA1を使っている場合は、ガジェットごとにコンシューマキーを設定し、ガジェットのリクエストをコンテナがProxyするという形を取っていました。これはShindigを使っているiGoogle、Orkut、hi5と、独自にOpenSocialを実装しているMySpaceとの方針の違いから来るものです。

HMAC-SHA1方式でコンテナをコンシューマとして扱おうとすると、シークレットは2者間のみで共有されなければならないため、コンシューマは、サービスプロバイダごとにキーとシークレットを発行しなければなりません。しかし、RSA-SHA1方式であれば、コンテナがコンシューマでも、公開鍵と秘密鍵の組み合わせは一つだけあれば使い回せるため、OpenSocialにおけるmakeRequest (Outbound OAuth)のように、コンテナが外部サービスからデータを取得するアーキテクチャの場合、RSA-SHA1方式にした方がコンシューマにとってサービスプロバイダの追加も容易になりますし、サービスプロバイダにとってコンシューマの署名を確認する作業も楽になるのが利点です。

ShindigがRSA-SHA1方式を中心に実装されているのはそんな理由がありそうです。ちなみに、Shindigの開発はGoogleが中心になって行われており、HMAC-SHA1方式についても現在実装中らしいですが、iGoogleでのコンシューマキーとコンシューマシークレットの発行は、メールで依頼することになっているため、今のところ本気で考えてはいなさそうです。

In the case of the iGoogle sandbox, you can send mail to oauthproxyreg@google.com with the following information to register your shared secret:
* URL of your gadget
* The shared secret assigned to you by the service provider
* The consumer key assigned to you by the service provider
* Whether to use symmetric or asymmetric signing with the service provider (or say that you don’t know)
Until your shared secret has been registered, your gadget will not work.  If you change the URL of your gadget, you will need to re-register the secret for that gadget.

まとめ

現時点ではOpenSocialのOutbound OAuthではMySpaceがHMAC-SHA1方式でガジェットをコンシューマに、Shindig系コンテナはRSA-SHA1方式でコンテナをコンシューマにしていますので、外部サーバーとやり取りを多なうOpenSocialガジェットを作る場合、どちらからのリクエストも受け付けられるよう構築しておく必要がありそうです。

参考サイト

View Comments add to hatena hatena.comment (6) add to del.icio.us (0) add to livedoor.clip (6) add to Yahoo!Bookmark (1) Total: 13

8月 06 2008

Data AvailabilityでOAuthを試す

Published by Eiji 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形式でデータが返ってきます。

サンプルアプリ

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

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

View Comments add to hatena hatena.comment (1) add to del.icio.us (0) add to livedoor.clip (1) add to Yahoo!Bookmark (1) Total: 3

8月 02 2008

OpenSocialのOAuthまとめ

Published by Eiji under OAuth, OpenSocial

OpenSocialでは、コンテナが外部サーバーとの通信を行う際、または外部サーバーがコンテナと通信を行う際、OAuthを使用して認可を行います。今回はOpenSocialにおけるOAuthについて、現段階でのまとめを書いてみます。 ※追記(2008/10/20):2008/10/4に書いたコチラの記事も必読です。

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“と呼ばれます。これはコンシューマとサービスプロバイダの信頼関係だけで、ユーザーによる認証を伴わない仕様のため、コンシューマがサービスプロバイダからパブリックな情報を取得したい場合に利用するケースが想定されます。 (かなり恥ずかしい間違いです。正確にはコンシューマが署名を付加することで、サービスプロバイダがリクエスト元とリクエスト内容に間違いがないことを確認できる仕様、です。/ 2009年10月追記)ちなみに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

※追記(2008/10/20):コンシューマシークレットについては、署名方式がRSA-SHA1の場合、必須ではありません。詳しくはコチラ。 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認証を行い、データを取得するところまでを試してみたいと思います。

View Comments add to hatena hatena.comment (18) add to del.icio.us (0) add to livedoor.clip (6) add to Yahoo!Bookmark (1) Total: 25

Next »