Archive for the 'OpenSocial' Category

4 月 23 2008

Cajaとは何か

Published by えーじ under OpenSocial

OpenSocial周りの調査をしていると、Cajaという言葉に遭遇します。セキュアなJavaScriptを実現するもの、ということだけ分かっていたのですが、詳細を調べてみました。

クロスサイトスクリプティングとブログパーツ

gooやlivedoor、fc2などのホスティングを含めたブログサービスを使ったことのある方はご存知と思いますが、サービスによってブログパーツが貼れるもの、貼れないもの、一部だけ許可しているものがあります。なぜでしょうか?

Cookieには同一ドメインから実行されたスクリプトしか参照できないという特徴があります。これを利用して、Cookieをセッション情報や閲覧履歴の保存場所として活用しているサービスは少なくありません。上記ブログサービスがブログパーツを許可しないのは、これらの情報を悪意のあるJavaScriptから守るためです。逆に言うと、同一ドメイン上でJavaScriptが実行できれば、そのセッション情報や閲覧履歴を盗むことができてしまいます。これをXSS(クロスサイトスクリプティング)と言います。

XSSが発生するのは、投稿フォームを使って、そのドメイン上のページにJavaScriptを埋め込み、実行できるケースが挙げられますが、ブログパーツが貼れること自体もJavaScriptが埋め込めるという意味では同じであり、まともに作られたサイトであれば、まずこういったことは出来ません。

とはいえ、実際にブログパーツを貼付けることができるブログは存在しますし、セキュリティの問題を回避しつつこれを実現するためのアプローチがいくつか存在します。

JavaScriptを貼付けるためのアプローチ

ドメインを分ける

ブログを表示するドメインをセッション情報等のクリティカルなCookieを保存していないものにしてしまいます。盗むものがなければ、泥棒が入ったところで何も困ることはありません。このアプローチをとっているものにはlivedoorブログが挙げられます。

安全性の確認できたJavaScriptのみ許可する

サービス提供者が安全なブログパーツのリストを作り、ブログ管理者がそこから選ぶ、というアプローチです。ブログパーツの選択肢が狭くなるためユーザーには好まれませんが、全く貼れないよりはよいはず。gooブログやはてなダイアリがこのアプローチをとっています。

iframeで表示する

iframe内に別ドメインで表示してしまえば、上記「ドメインを分ける」と同様に扱うことができます。このアプローチを取っているものにiGoogleが挙げられます。iGoogleはブログではありませんが、ブログパーツ=ガジェットと捉えれば同じ問題を扱っていると言えます。

JavaScriptの危険な部分を無力化する

サーバーがJavaScriptを出力する前に危険な部分を書き換え、無力化してしまいます。このアプローチをとっているブログがあるか知りませんが、やり方としては誰でも思いつくのではないでしょうか。ただ、これを実現するためには膨大な労力と知識が必要となります。これがオープンソースで存在しているとすれば、どんなに素晴らしいでしょう。そして、これを実現することができるのが今回紹介する、Cajaです。

Cajaで実現できること

Cajaはカハと読みます。CajaはGoogleのオープンソースプロジェクトの名前で、これを使うことで、同一ドメイン上のページに安全に外部のJavaScriptを貼付けることが可能になります。

Caja紹介(日本語訳)

開発に当たってCajaを使って防がれるべきとされた攻撃方法の一覧

どこでCajaを使うのか

CajaはOpenSocialコンテナ上での利用を想定して作られているようです。Caja紹介(日本語訳)の説明も、Shindigでアプリケーションを利用することが前提となっており、Cajaを使ってガジェットをインラインで表示した方がパフォーマンスが向上する旨が記載されています。

Cajaの形態

実はここがまだ調べきれていない部分なのですが、どうやらJavaによるサーバーサイドでのリライトと、JavaScriptのライブラリで構成されている、ぽいです。この辺はもう少し調べる必要がありそうです。

何か他に情報をお持ちの方がいらっしゃいましたらぜひ、教えてください。

Comments

4 月 22 2008

ついにiGoogleがOpenSocial対応へ

Published by えーじ under OpenSocial

今日から、OpenSocial機能提供に向け、iGoogleでsandboxの利用が可能になりました。これは明白に、Google自身がソーシャルネットワークを基盤とした仕組みになっていくことを意味しています。以前Maka-Makaと呼ばれるプロジェクトが存在し、Google独自のSNSサービスが始まるという話題がありましたが、それがOpenSocialというオープンな形を取り、予想していたとはいえ、iGoogleという形で現実のものにされると、さすが、としか言いようがありません。

で、早速試してみました。

まずはサインアップ。こちらからできます。(言語設定は英語にしておかないと、サインアップしてもsandboxが利用できないようです。)

http://code.google.com/apis/igoogle/docs/anatomy.html

これが新しいiGoogleの画面。

画面左にあるのがインストールしたアプリケーション/ガジェット。これをクリックするとキャンバスビューが開きます。

画面右側にはUpdateとしてアクティビティストリーム(行動履歴)が表示されるとのことですが、まだ確認できていません。SNSですから、友達リストがあってもおかしくないのですが、sandboxでは友達なしの状態からスタートし、sandboxに登録しているユーザー同士でなければ友達になれないとのこと。どうやって友達になれるかは、まだ不明。実際のサービス時はGoogle Talk/Gmailのアドレス帳からスタートすることは容易に想像できます。

また他にも、ガジェットごとの設定項目の表示方法が変更されているようです。

で、せっかくのsandboxですから、早速以前作ったFriendIntroducerを試してみました。OpenSocialとはいえ、コンテナごとにビュー名は若干違うよね、ということで、ガジェットXMLにhomeビューを追記し、Developerガジェットから追加。

んー。友達がいないので、当然こういう表示になってしまいますが、動いていることは確認できました。やはりそこはOpenSocial。

まとめ

あくまで基盤とはいえ、Googleは本当に恐ろしい存在です。すべてのウェブサービスを飲み込めるくらい、地を這ってる。auやlivedoorのGmailしかり、Google App Engineしかり。何でもかんでもGoogleに乗っけてしまえってくらい。

そしてGoogleにはAndroidもあります。そう、携帯電話のアドレス帳もこの友達リストに接続できるようになるでしょう。そうすると、友達のブログ更新をメールで受け取ったり、そのままケータイで閲覧したりといったことがユーザーに何のストレスも与えずに可能になります。

あと足りないのはプロフィールビューでしょうか。Google MapやGoogle Groupsで部分的に実現されてはいますが、これがどういう形で結実していくか、見物です。

Comments

4 月 17 2008

OpenSocialアプリケーションを作る(2)

Published by えーじ under OpenSocial, Widget

OpenSocialアプリケーションを作る(1)では、ガジェットの仕組みと、Orkutでアカウントを取得するところまで書きました。今回は、前回紹介したアプリケーションのコードを解説します。

このアプリケーション(FriendIntroducer)は、自分が見た場合は友達の紹介文を書くことができ、他人が見た場合はその人に向けて書かれた紹介文を読むことができる、というmixiなどにもよくある簡単なアプリケーションです。JavaScriptやjQuery的にはもっと賢い実装方法があると思いますが、今回はOpenSocialのコードにフォーカスしますので、アホなコードは大目に見てください。

ガジェットXML

< ?xml version="1.0" encoding="UTF-8" ?>
<module>
<moduleprefs title="Friend Introducer" title_url="" description="Introduce your friend!" height="100">
  <require feature="opensocial-0.7" />
  <require feature="views" />
  <require feature="dynamic-height" />
 </moduleprefs>
<content type="html" view="canvas">
  < ![CDATA[
  <link href="http://devlab.agektmr.com/OpenSocial/css/FriendIntroducer.css" rel="stylesheet" type="text/css">
  <script type="text/javascript" src="http://devlab.agektmr.com/OpenSocial/js/jquery.js"></script>
  <script type="text/javascript" src="http://devlab.agektmr.com/OpenSocial/js/FriendIntroducer.js">< /script>
  </script><script type="text/javascript">
    gadgets.util.registerOnLoadHandler(FriendIntroducer.init);
  </script>
  <div id="title"></div>
  <div id="friends"></div>
  <div id="message"></div>
  ]]>
 </content>
</module>

ここでは

  • ガジェットの設定
  • 外部のCSSやJavaScriptを読み込み
  • 初期化スクリプトの呼び出し
  • 表示用DIV指定

を行っています。

<content type="html" view="profile">

Contentはhtmlタイプ、profileビューと指定しました。typeにはhtmlとurlが選択可能ですが、htmlとして内容をContentタグで囲まれた部分に記述しています。viewはOpenSocialの仕様上profile、canvasが想定されていますが、コンテナによってhomeやpreviewが存在するようです。ここでは例としてcanvasを使用しています。

また、viewを指定しない場合はdefaultビューとして扱われます。コンテナは表示場面(コンテキスト)によってビューを切り替えますが、Content内でviewを取り出してJavaScriptで処理を分ける方法もあります。

Contentの内容

Contentの内容は、基本的に通常のウェブページと同じように扱うことができ、HTMLで書くことができますが、

  <script type="text/javascript">
    gadgets.util.registerOnLoadHandler(FriendIntroducer.init);
  </script>

このようにgadgets.util.registerOnLoadHandlerを使って初期化処理を入れることができます。

このアプリケーションでは、表示テンプレートとして空のdivタグを3つ用意しています。

JavaScriptのコード

JavaScriptのソースコードはここにありますが、抜粋して紹介します。

    $('#friends').html('Requesting friends...');
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
    req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'friends');
    req.add(req.newFetchPersonAppDataRequest('VIEWER', 'Introduction'), 'intro');
    req.send(FriendIntroducer.onLoadViewerFriends);

最も基本的な処理となる、閲覧者、閲覧者の友達、保存したデータを取り出す処理です。

opensocial.newDataRequest()でデータリクエストオブジェクトを作り、addで3種類のリクエストを追加、最後にsendでコールバック関数を指定した上、データリクエストを送信しています。3種類のリクエストにはそれぞれ後で区別するためviewer, friends, introという名前(キー)を付けています。

   var viewer    = response.get('viewer').getData();
   var friends   = response.get('friends').getData();
   var intro     = response.get('intro').getData();

コールバック関数では、引数(response)を使って、response.get(キー名).getData()でリクエストしていたデータを取り出すことができます。

    var viewer_id = viewer.getId();
    var json = null;
    if (intro[viewer_id]) {
      if (intro[viewer_id].Introduction) {
        var json_str = gadgets.util.unescapeString(intro[viewer_id].Introduction);
        var json = eval(json_str)[0];
      }
    }

introは、このアプリケーションを使ってコンテナのデータ保存領域に予め保存しておいた内容、つまり「以前保存した友達の紹介文」です。

    $('#title').html('<p>Friends of '+viewer.getDisplayName()+':</p>');
    var html = '';
    if (friends.size() == 0) {
      $('#message').html("<p>You don't have any friends yet!</p>");
    }

友達が誰もいない場合を考慮して、メッセージを表示しています。

    friends.each(function(person) {
      var t = FriendIntroducer.template.friend_list_canvas;
      t = t.replace('##thumbnail_url##', person.getField(opensocial.Person.Field.THUMBNAIL_URL));
      t = t.replace('##profile_url##',   person.getField(opensocial.Person.Field.PROFILE_URL));
      t = t.replace('##display_name##',  person.getDisplayName());
      t = t.replace('##input_id##',      'input_'+person.getId());
      if (json) {
        t = t.replace('##intro_text##',  json[person.getId()] ? json[person.getId()] : '');
      } else {
        t = t.replace('##intro_text##', '');
      }
      html += t;
    });
    $('#friends').html('<ul>'+html+'</ul>');

OpenSocialでは配列をなめる、いわゆるiterationも仕様に含まれていて、eachを使うことができます。ここでは、友達のリストをループして、友達の名前やサムネイル画像、保存されていた紹介文をHTMLテンプレートに埋め込んでいきます。

ここまでで、友達の紹介文を書き込むことができるcanvasページの表示することができました。次に、友達の紹介文をユーザーが書き込んだものと想定し、投稿して保存するところまでを解説します。

データの保存

OpenSocialはコンテナにデータ保存領域を持っており、アプリケーションがデータを保存することができます。これはパーシステントデータ(Persistant data)や、アプリケーションデータ(AppData)と呼ばれています。アプリケーションデータはバージョン0.7ではエスケープした文字列のみサポートしています(次のバージョンではJSONそのものの保存も可能になるようです)。

    var list = $('#friends ul li');
    var intro = "{result:[{";
    for (var i=0; i < list.length; i++) {
      var textarea = list[i].lastChild.lastChild;
      var uid = textarea.id.substring(6);
      var intro_text = textarea.value.replace("'", "\\'");;
      intro += "'"+uid+"':'"+intro_text+"'";
      intro += (list.length-1)==i ? "" : ",";
    };
    intro += '}]};';
    var req = opensocial.newDataRequest();
    intro = gadgets.util.escapeString(intro);

この処理は、ユーザーが友達の紹介文を書き終わって「投稿ボタン」を押すことでトリガーされるものです。DOMを辿って各友達のユーザーIDと紹介文の内容を取得する、普通のJavaScriptです。取得した内容はJSONの文字列になるよう連結し、エスケープすることで、アプリケーションデータとして保存が可能になります。

    req.add(req.newUpdatePersonAppDataRequest('VIEWER', 'Introduction', intro));
    req.send(function() {
      $('#message').html('<p>Your introduction has been submitted.');
    });

最後に、JSON形式になった文字列をデータリクエストオブジェクトに追加して送信して、完了です。

まとめ

解説というよりはソースコード並べただけみたいな記事になってしまいましたが、OpenSocialアプリケーションのほとんどがJavaScriptでできてしまうということは、分かったかと思います。次回は外部サーバーとの連携を行うmakeRequestに触れたいと思います。

Comments

4 月 16 2008

OpenSocial API仕様を翻訳しました

Published by えーじ under OpenSocial

OpenSocial API仕様 (v0.7)を翻訳しました。

Tender Surrender » OpenSocial/OpenSocial API仕様 (v0.7)

Comments

4 月 08 2008

OpenSocialとかどうよ?的な勉強会(!?)に参加してきた

Published by えーじ under OpenSocial

百式の中の人がやっているIDEAxIDEAというブログで募集があった「OpenSocialとかどうよ?的な勉強会」に行ってきました。場所は汐留のMySpaceジャパンオフィス。本国からエンジニアが来日しているとのことで、聞きたいことリストを用意しての参加です。

MDPとOpenSocialの関係

MDPとはMySpace Development Platformの略。MDPはOpenSocialより広い範囲のAPIです。言い換えると、OpenSocialはMDP上に作られている、とのこと。

OpenSocialではJavaScriptが先行して仕様決定されていっていますが、コンテナプロバイダはAjaxを受け付けるREST APIを作らないとRequestに対して応答を返すことが出来ません。そこでMySpaceの開発した仕様がMySpace REST APIでした。(当然、Orkutやhi5にもこれに類するものがありますが、仕様は未公開です。hi5はあったかな?)

MySpaceにはOpenSocialとは別にMyOpenSpaceという拡張があり、opensocialreference.jsとMyOpenSpace.jsとして区別されています。位置付けとしてはMyOpenSpaceがまずあり、それをラッピングする形でOpenSocialが存在する、と言った方が正確でしょう。OpenSocialは様々なSNSの持つAPIの最大公約数を取る形でデザインされているため、独自のAPIをラッピングすれば十分な訳です。確かにこれなら、他社SNSからアプリを持ってきたとしても、OpenSocialに対応したJavaScriptでさえあれば、互換性が保てますね。

また、RESTful APIについてはOpenSocial版が登場したときにどうするつもりか?という質問をしてみたのですが、「APIを増やすだけだよ」という回答。なるほど。そりゃそうだ。現行バージョンでアプリを開発した人向けに、古いバージョン用のAPIも残していくようです。

これで、以前から気になっていたMySpaceはまだ仕様が固まっていないはずのOpenSocial RESTful APIをどうやって実装したのか?という疑問が解決しました。

OpenSocialの拡張に当たる部分とは?

  • フォトアルバム
  • ヒーロー
  • 好みの映画

等々が既に存在する独自拡張で、最も利用されているのがフォトアルバム。確かにフォトアルバムはSNSによってあったりなかったりしつつも、使われそうな機能ですね。

また、個別送信可能なメッセージ機能は?と聞いたところ、今まさに開発中だそうです。(今見たら、OpenSocialにもうあるような、、、)他にも、音楽やコメディなど、様々な分野のAPIを作っていきたいとのことでした。

アプリケーションの登録について

アプリ開発者はSandboxのアカウントを取得すればすぐに開発を始めることが出来ますが、実際にアプリを公開するためには審査を通る必要があります。審査はコードのレビューやリーガルチェック(著作権侵害等)を経て、だいたい24時間〜48時間で公開されますが、権利関係が微妙な場合はもっとかかることもあるとのこと。

聞きそびれてしまいましたが、アプリをXMLでリモートサーバーに置いた場合でも、一度アプリが審査を通過してしまうと、GoogleGadgetのようにそれ以降のサーバー上のXMLの変更は反映されないと思われます。

メモ

  • Install Callback URL、Uninstall Callback URLはそれぞれ、ユーザーがアプリをインストール、アンインストールした直後にリダイレクトされるページのURLを指定できる。デフォルトはアプリのキャンバスページ。
  • OAuthの認可用にキーとシークレットが発行される。

マネタイズ

当然メインは広告収入になると思われますが、Facebookのようにある種のレコメンド広告で収益を得る方法もありえます。他にも、アプリ開発者に対して課金することで表示位置を優遇したり、といったことも考えられます。

今のところアプリ開発者は、自社サービスの会員獲得を目的としてアプリを提供するケースが多いようですが、キャンバスビューで全画面を使うことができますので、ここに好きなように広告を入れて収益を上げてよいとのこと。将来的にはアプリを使って物販や課金する方法の提供も検討しているとのことで、夢が広がります。

アプリケーションの互換性

以前から疑問だったOpenSocialアプリケーションのSNS間の互換性について。実は自分の中では答えが出てたのですが一応聞いてみました。

まず、MySpace独自拡張の部分を利用しなければ、当然他のSNSに持って行っても使うことが出来ます。まあ、そりゃそうですよね。でも、viewやcssはサイトごとに切り替える必要があるはず。例えばOrkutではcanvas、profileという2つのviewしかありませんが、MySpaceにはhome,canvas,profile.left,profile.rightの4つが、hi5にはhomepage,canvas,profileという3つがあります。この時点で、うーん、ですね。

ただ、やり方として、コンテナのメソッドにアプリが動いているコンテナの名前を取得するAPIがあるので、それによって動作を切り替える方法もあるよ、と教えてもらいました。なるほど。

リモートサーバーにアプリを実装できるか?

RESTful APIを使えば当然外部サイトでもアプリを使えるのですが、ここではGoogleGadgetのContent type=’html’をtype=’url’にできるか?という話です。

答えは、イエス。

当然、同じドメイン配下にプロキシを作って、OAuthでMySpaceのAPIを叩く仕組みを作らなければならない訳ですが、サーバー用ライブラリも用意(準備中?)されているそうです

アプリケーションディレクトリ公開後の伸び

Facebookはアプリケーション機能公開後に急激な伸びを示した訳ですが、MySpaceについてはどうか?聞いてみたところ、今のところ目立って急激な伸びは見られないとのこと。サイト上にもあまり誘導を貼っていないことから、まだその段階に達していないとの判断と伺えます。今後APIがもっとしっかりしたものになってから、色々やるんでしょうね。メッセージ機能等による口コミにも期待しているそうです。

escapeStringとunescapeStringについて

パーシステントAPIを使う際、文字列情報しか保存できないため、JSON形式でやりとりされます。その際文字列をエスケープしてから投げたり、受け取った際はアンエスケープする必要があるのですが、Orkutやhi5で使えたgadgets.util.escapeString()とgadgets.util.unescapeString()がMySpaceで使えなかったため質問してみました。

答えはescapeStringとunescapeStringはもう使われていないはずで、今はencodeURIComponentが推奨のはずだよ、とのこと。今OpenSocialの仕様を見てみたところ、まだgadgets.util.scapeString()もgadgets.util.unescapeString()も有効のようですが、、、。

MySpace用のサンプルアプリ

以前作った友達紹介アプリのMySpaceバージョンを公開します。

http://devlab.agektmr.com/OpenSocial/MySpace/FriendIntroducer.xml

別の人がこのアプリを自分のSandboxアカウントに入れることができたか分かりませんが、参考になれば。MySpaceに2つアカウント作って試すところまではまだやっていないため、物好きな方はMySpaceの僕のアカウントに友達申請してください。

感想

  • MySpaceのエンジニアの方はAptanaを使う人が多いみたい。Javaアプリはもっさりしてて嫌いなので基本的に使わないのですが、もう一回チャレンジしてみようかな・・・。
  • 何が驚いたって、参加者10人中パソコン出した人が4人。その全員がMacBook Airユーザーだったこと!
    みんなリッチだなあ。 
  • Ozzieと写真撮ってもらった!
参加者の皆様、お疲れ様でした。

※追記(4/12)

「escapeStringとunescapeStringがもう使われていない」というのは間違いではないか?の件について、当日教えてくれたTerrenceにメールで確認しました。

どうやら「escape」と言ったのを、一般的なJavaScriptのescapeと勘違いしたらしく、彼が言っていた「escapeはもう使われていない」というのは、そちらを指していたとのこと。確かに、今はescapeよりもencodeURIComponentを使うように推奨されてますね。

で、本題のgadgets.util.escpeStringとgadgets.util.unescapeStringについては、確かに、MySpaceでは実装されていないそうです。自分で解決するしかないみたい。

Comments

« Prev - Next »