Archive for 8 月 8th, 2010
FlashからOAuth認証でTwitterから発言できるのか?
TwitterのBACIS認証でのAPI提供がもうじき8月16日に停止されます。
みなさんの使っているアプリはもうOAuth認証に対応しているものでしょうか?
そこで新しい(といってもだいぶ前から提供されていました)OAuth認証をFlash(AS3.0)で出来るのか試してみました。
今までのBACIS認証では各TwitterクライアントにID,PASSを登録してつぶやき等を行っており第三者にID,PASSを預けていました。それではセキュリティ的に問題があると言う事で、OAuth認証が採用されたそうです。
OAuth認証とは、クライアントをTwitterのアカウントで認証する(Twitterのページで認証を行う。下図)とキーがクライアントに渡され、以後認証などをする事なぐTwitterの機能を使えるようになるものです。
しかし、このOAuth認証を知らない人は多いと思います。
一度認証を許可してしまうと、そのクライアントアプリはTwiiterの操作権を持つことになり、それいこう認証なしでつぶやき等が出来てしまいます。(認証はTwitterサイトでいつでも任意で解除することができます。なので一度アクセス権を取得したアプリは認証が解除されるまで、アクセス権を保持しています。)
つい先日から大量にやってくる、マイケルジャクソンのDMもこのOAuth認証を利用したものです。知り合いから送られてくるので、気軽にDMを見てリンク先をクリックするとTwitterの認証画面に進みます。そしてTwitter上のページだからといって安心して許可ボタンを押すと、その瞬間にこのアプリに自分のアカウントの操作権利を渡してしまい、結果、自分のフォロワーにDMを大量に送ってしまう事になってしまうのです。
こんな、ちょっとややこしいOAuth認証をFlash(ActionScript3.0)のみでできるのかが今日の本題です。
結論としてはFlashのみでWEBアプリとしてOAuth認証できませんでした。
なぜなら、twitterではクロスドメインが解放されておらず、Flashからいっさい通信することができないからです。なので、ローカルでの場合?を想定して進んで行きます。AIRだとクロスドメインも関係ないので出来るのではないでしょうか。
だいたいの流れはこうのようになります。
1、twitterでアプリを登録する(consumerKey, consumerSecretの発行)
2、ユーザーがアプリのアクセスを承認
3、PIN(7桁の数字)を取得
4、アクセストークン(Key, Secret)を取得
5、つぶやく
Flashで制作して行きますが、フルスクラッチで行うのは厳しいので、ライブラリをふんだんに使って行きます。また、Flexのライブラリも利用しましたので、FlexのSDKをダウンロードしFlashからクラスパスを通しておきます。クラスパスの設定(SDKpass)/frameworks/libsを設定すだけでflashでもmxライブラリが使えるようになります。といってもグリッドなどのコンポーネントが使える訳ではないです。
今回利用したライブラリ
1、twitterでアプリを登録する(consumerKey, consumerSecretの発行)
まず始めにTwitterのサイトに行き、設定>関連アプリ>開発者のかたへ>新しいアプリケーションの追加と進み、アプリケーションを登録します。ここではアプリケーションの名称、開発者、詳細、アイコン設定等の設定をこないます。ここで、クライアントアプリケーションかブラウザアプリの選択を行います。これは上記3でPINを取得後の処理が違います。ブラウザアプリではPIN取得後、設定URLにリダイレクトされます。クライアントアプリではPINが表示されるようになります。今回はローカルでの作業ですのでクライアントアプリケーションにしました。登録が完了するとconsumerKey, consumerSecretを取得できます。このconsumerKey, consumerSecretは今回の最終的な認証の鍵の鍵の鍵の鍵のようなものだと思います。
2、ユーザーがアプリのアクセスを承認
ここからがASによる作業になります。
oauth = new OAuth(consumerKey, consumerSecret);
loader = oauth.getRequestToken("http://twitter.com/oauth/request_token");
loader.addEventListener(Event.COMPLETE, requestTokenHandler);
consumerKey, consumerSecretには1で取得した文字列を入れます。
このリクエストで、3でPINを取得する為の認証先のURLを作る為のrequestTokenを作ります。必要な値を入れるだけで殆どライブラリがやってくれます。
3、PIN(7桁の数字)を取得
requestToken = OAuthUtil.getTokenFromResponse(e.currentTarget.data as String);
var request:URLRequest = oauth.getAuthorizeRequest("http://twitter.com/oauth/authorize", requestToken.key);
navigateToURL(request, "_blank");
認証ページへのURLの生成です。といってもここもライブラリが全部やってくれています。
ここでnavigateToURLをしていますが、ここで一度Twitterのサイトに行く事でアプリの認証を行います。そしてPINをサイト上に表示させる、または1で登録したページへのリダイレクトを利用してPINを取得します。
今回はサイトに表示させ、それを手でコピペしましたが、AIR等ではWindowでブラザを開く事が出来るので、コールバックの実装も出来ると思います。今回ここは省略です。
4、アクセストークン(Key, Secret)を取得
var loader:URLLoader = oauth.getAccessToken("http://twitter.com/oauth/access_token", requestToken, {oauth_verifier:pin});
loader.addEventListener(Event.COMPLETE, accessTokenHandler);
3で取得したPINでAccessTokenを取得します。このAccessTokenはがOAuth認証の最後の鍵となります。なので一度認証を行いAccessTokenを所得したら、ユーザーがアプリの認証を解除するまで有効となります。Flashなどで利用する場合SharedObjectなどで保存してけば、次回からは認証なしでTwiiter機能が使える様になります。
5、つぶやく
いよいよつぶやきですが、ただ単にリクエストを送るだけではつぶやく事は出来ません。
var consumerToken:OAuthConsumer = new OAuthConsumer(consumerKey, consumerSecret);
var oauthReq:OAuthRequest = new OAuthRequest("POST", "http://api.twitter.com/1/statuses/update.xml", {oauth_version: "1.0", status: msgb.text}, consumerToken, accessToken);
var auth:String = oauthReq.buildRequest(new OAuthSignatureMethod_HMAC_SHA1, OAuthRequest.RESULT_TYPE_POST);
auth = auth.split("&").join("\",");
auth = auth.split("=").join("=\"");
auth = auth.replace(/,status=.*/, "");
var authHeader:URLRequestHeader = new URLRequestHeader("Authorization", "OAuth " + auth);
var req:HttpRequest = new Post();
req.addHeader("Authorization",authHeader.value);
req.setFormData([{
name:"status",
value:msgb.text
}]);
var client:HttpClient = new HttpClient();
client.addEventListener(HttpRequestEvent.COMPLETE, twtcomp);
client.request(new URI("http://api.twitter.com/1/statuses/update.xml"), req);
通常のURLRequest,URLLoaderではカスタムのヘッダーの利用が出来ないそうで、ここでもライブラリです。Signatureの生成等や、つぶやき本文への追加したヘッダーを作り、HttpRequestを利用してリクエストしてつぶやき完了です。これだとつぶやきっぱなしになってしますので、HttpRequestEvent.COMPLETEイベントを追加してリクエスト監視しています。これで終了です。

実際にtwitterで確認してみると、発言元のviaの箇所が登録したアプリ名になっているのが確認できます。
結論として、ローカルアプリならflashのみでOAuthできる事が分かりました。けど、セキュリティサンドボックスの壁がある以上やっぱFlashだけでは無理なので、webアプリの場合はやっぱり無理なんだろうか?8月16日以後の動向に注目です。
今回はこの記事を書くにあたってこちらのブログを大変参考にさせて頂きました。有り難うございました。



