AIRでOAuth2認証するには?
AIRでAdSenseから取得したデータを表示させてみようと思った。
Getting Started - AdSense Management API - Google Code
しかし、そのためにはOAuth2認証を通す必要があるようだ。では、AIRでOAuth2認証するにはどうしたらいいのか?
「API Console」で必要な情報をそろえる
まずOAuth2で必要な情報を集めるために、API Consoleに逝く。
新しいプロジェクトを作る。ここでは「OAuth2Test」とした。
プロジェクトを作ると自動的に開く「services」で「AdSense Management API」を「ON」する。
「API Access」ページに逝って「Create an OAuth 2.0 client ID」という青くてデカいボタンクリック。
「Product Name」を入力して「Next」。ここでは「OAuth2Test」とした。「Product Logo」は放っておいておk。
「Application Type」として「Installed Application」を選んで「Create client ID」。
すると、「Client ID」「Client secret」「Redirect URIs」がもらえる。これらがOAuth2で必要な情報だ。
ユーザーに許可を求めるページを表示して「code」を取得
ユーザーにAdSenseへのアクセスの許可を求めるページを表示して、「code」を取得する必要がある。
そのために、StageWebViewを使う。コードはこんな風。
まず、StageWebViewをフルスクリーンで表示して許可を求めるページを表示する。
許可ページのURLをcreateAuthURL()で作る時に、redirect_uriとclient_idに、API Consoleでもらった情報を使う。
もう一つのポイントは「scope」の指定の仕方。このscopeの種類はここに書いてあった。
Getting Started - AdSense Management API - Google Code
多分、他のAPIのドキュメントにも同様の記述があるのだろうと思われ。
許可ページでユーザーが許可を出すとページが切り替わる。そのページのタイトル部分に必要な「code」が含まれているので切り出す。
「access_token」を取得
codeを切り出したと同時に、codeを使ってaccess_token取得のリクエストを「https://accounts.google.com/o/oauth2/token」に投げる。
ここで注意が必要なのは
・このURLへのリクエストはPOSTで行う(GETは受け付けない)
・レスポンスはJSONで返ってくる
ということだ。
今回はこのように、URLへのリクエストにHTTPServiceを使うことにした。
リクエストが成功した時の処理はこんな風。
JSONはFP11.0/AIR3.0から使えるようになったクラスだ。最近のREST型のサービスのレスポンスはXMLではなくほとんどJSONなので、そろそろサポートしてくれないと困っちゃうわいな。
今回はFB4.6で開発したので問題なかったけど、FP10系も対応させたいと思うと独自にJSONを扱えるライブラリを組み込むことになりそうだ。
そして、このリクエストが完了した時点で「swv.stage = null;」してWebViewを非表示にするところも重要。
ところで、access_tokenが取得できたらOAuth2認証はできたということだ。つまり、ここまでで認証処理はおしまい。
AdSenseの日毎の売上レポートをリクエストする
ちゃんと認証できたのかを確かめるために、実際にAdSenseに2012年1月の日毎の売上レポートをリクエストしてみる。
このリクエストに対応するのは「https://www.googleapis.com/adsense/v1.1/reports」だ。
AdSenseに限らないけど、GoogleのAPIでどんなメソッド(リクエスト先)があるかや、そのパラメーターにはどんなものがあるかは「APIs Explorer」でわかる。
Google APIs Explorer
今回もまた、このようにHTTPServiceを使う。
実際にリクエストを送る部分はこんな風。
ここでaccess_tokenが必要なのだ。
レスポンスはまたJSONで返ってくるので、あとはグラフにするなど、好きな処理をすればいい。今回は単にTextAreaに表示させた。
全コード
最後に、全コードをこぴぺ。個人情報の部分は「xxx」した。
もちろん、このコードをどのように使っていただいても結構です。ただし、無保証、サポート無しです。
以上、終了!うぃーあうちょ〜!
Getting Started - AdSense Management API - Google Code
しかし、そのためにはOAuth2認証を通す必要があるようだ。では、AIRでOAuth2認証するにはどうしたらいいのか?
「API Console」で必要な情報をそろえる
まずOAuth2で必要な情報を集めるために、API Consoleに逝く。
新しいプロジェクトを作る。ここでは「OAuth2Test」とした。
プロジェクトを作ると自動的に開く「services」で「AdSense Management API」を「ON」する。
「API Access」ページに逝って「Create an OAuth 2.0 client ID」という青くてデカいボタンクリック。
「Product Name」を入力して「Next」。ここでは「OAuth2Test」とした。「Product Logo」は放っておいておk。
「Application Type」として「Installed Application」を選んで「Create client ID」。
すると、「Client ID」「Client secret」「Redirect URIs」がもらえる。これらがOAuth2で必要な情報だ。
ユーザーに許可を求めるページを表示して「code」を取得
ユーザーにAdSenseへのアクセスの許可を求めるページを表示して、「code」を取得する必要がある。
そのために、StageWebViewを使う。コードはこんな風。
protected function onClickBtnStartOAuth2():void { swv = new StageWebView(); swv.addEventListener(Event.COMPLETE, onCompleteSWV); function onCompleteSWV(evt:Event):void { const codeSubstringKey:String = "code="; var title:String = swv.title; //「code」はタイトルに含まれている trace("onCompleteSWV() title=[" + title + "]"); var idx:int = title.indexOf(codeSubstringKey); if (idx != -1) { //「code」を切り出し code = title.substring(idx + codeSubstringKey.length); trace("onCompleteSWV() code=[" + code + "]"); //codeを元にaccessTokenをリクエスト(grant_typeはInstalledAppの場合はこれで固定) getAccessToken.send({"code":code, "client_id":CLIENT_ID, "client_secret":CLIENT_SECRET, "redirect_uri":REDIRECT_URI, "grant_type":"authorization_code"}); } } swv.stage = stage; //WebView表示開始(WebViewはディスプレイリストに追加できないのでフルスクリーンになる) swv.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); swv.loadURL(createAuthURL()); //許可ページリクエスト } protected function createAuthURL():String { var url:String = "https://accounts.google.com/o/oauth2/auth?" //ここに投げることになってる + "scope=" + escapeMultiByte("https://www.googleapis.com/auth/adsense.readonly") //許可を得たいサービス + "&redirect_uri=" + REDIRECT_URI + "&response_type=code" //InstalledAppだとこの値で固定 + "&client_id=" + CLIENT_ID return url; }
まず、StageWebViewをフルスクリーンで表示して許可を求めるページを表示する。
許可ページのURLをcreateAuthURL()で作る時に、redirect_uriとclient_idに、API Consoleでもらった情報を使う。
もう一つのポイントは「scope」の指定の仕方。このscopeの種類はここに書いてあった。
Getting Started - AdSense Management API - Google Code
多分、他のAPIのドキュメントにも同様の記述があるのだろうと思われ。
許可ページでユーザーが許可を出すとページが切り替わる。そのページのタイトル部分に必要な「code」が含まれているので切り出す。
「access_token」を取得
codeを切り出したと同時に、codeを使ってaccess_token取得のリクエストを「https://accounts.google.com/o/oauth2/token」に投げる。
ここで注意が必要なのは
・このURLへのリクエストはPOSTで行う(GETは受け付けない)
・レスポンスはJSONで返ってくる
ということだ。
今回はこのように、URLへのリクエストにHTTPServiceを使うことにした。
<!-- JSONで返ってくるのでresultFormatをtextに。このURLにはPOSTでリクエストをなげることになってる。 --> <s:HTTPService id="getAccessToken" url="https://accounts.google.com/o/oauth2/token" method="POST" resultFormat="text" result="onResultGetAccessToken(event);" fault="onFaultGetAccessToken(event);"/>
リクエストが成功した時の処理はこんな風。
protected function onResultGetAccessToken(evt:ResultEvent):void { var result:String = getAccessToken.lastResult as String; taAccessToken.text = result; trace("onResultGetAccessToken():" + evt + "\n" + result); var json:Object = JSON.parse(result); //JSONをパース accessToken = json.access_token; trace("onResultGetAccessToken():access_token=" + accessToken); swv.stage = null; //WebViewを非表示にする }
JSONはFP11.0/AIR3.0から使えるようになったクラスだ。最近のREST型のサービスのレスポンスはXMLではなくほとんどJSONなので、そろそろサポートしてくれないと困っちゃうわいな。
今回はFB4.6で開発したので問題なかったけど、FP10系も対応させたいと思うと独自にJSONを扱えるライブラリを組み込むことになりそうだ。
そして、このリクエストが完了した時点で「swv.stage = null;」してWebViewを非表示にするところも重要。
ところで、access_tokenが取得できたらOAuth2認証はできたということだ。つまり、ここまでで認証処理はおしまい。
AdSenseの日毎の売上レポートをリクエストする
ちゃんと認証できたのかを確かめるために、実際にAdSenseに2012年1月の日毎の売上レポートをリクエストしてみる。
このリクエストに対応するのは「https://www.googleapis.com/adsense/v1.1/reports」だ。
AdSenseに限らないけど、GoogleのAPIでどんなメソッド(リクエスト先)があるかや、そのパラメーターにはどんなものがあるかは「APIs Explorer」でわかる。
Google APIs Explorer
今回もまた、このようにHTTPServiceを使う。
<!-- JSONで返ってくるのでresultFormatをtextに。 --> <s:HTTPService id="reportsGen" url="https://www.googleapis.com/adsense/v1.1/reports" resultFormat="text" result="onResultReportsGen(event);" fault="onFaultReportsGen(event);"/>
実際にリクエストを送る部分はこんな風。
protected var startDate:String = "2012-01-01"; protected var endDate:String = "2012-01-31"; protected var dimension:String = "DATE"; protected var metric:String = "EARNINGS"; public function requestReportsGen():void { trace("requestReportsGen()"); reportsGen.send({"startDate":startDate, "endDate":endDate, "dimension":dimension, "metric":metric, "key":API_KEY, "access_token":accessToken}); }
ここでaccess_tokenが必要なのだ。
レスポンスはまたJSONで返ってくるので、あとはグラフにするなど、好きな処理をすればいい。今回は単にTextAreaに表示させた。
全コード
最後に、全コードをこぴぺ。個人情報の部分は「xxx」した。
もちろん、このコードをどのように使っていただいても結構です。ただし、無保証、サポート無しです。
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="640" height="480" > <!-- 各種定義 --> <fx:Declarations> <!-- JSONで返ってくるのでresultFormatをtextに。このURLにはPOSTでリクエストをなげることになってる。 --> <s:HTTPService id="getAccessToken" url="https://accounts.google.com/o/oauth2/token" method="POST" resultFormat="text" result="onResultGetAccessToken(event);" fault="onFaultGetAccessToken(event);"/> <!-- JSONで返ってくるのでresultFormatをtextに。 --> <s:HTTPService id="reportsGen" url="https://www.googleapis.com/adsense/v1.1/reports" resultFormat="text" result="onResultReportsGen(event);" fault="onFaultReportsGen(event);"/> </fx:Declarations> <!-- スクリプト --> <fx:Script> <![CDATA[ import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; //OAuth2の許可ページ表示用WebView protected var swv:StageWebView; //APIs Consoleでもらった情報 protected const CLIENT_ID:String ="xxx"; protected const CLIENT_SECRET:String = "xxx"; protected const REDIRECT_URI:String = "urn:ietf:wg:oauth:2.0:oob"; //InstalledAppだとこの値は固定らしい。「http://localhost」だとエラー出た。 protected const API_KEY:String = "xxx"; //欲しい情報 [Bindable] protected var code:String; //accessTokenをもらうために必要 [Bindable] protected var accessToken:String; //APIにアクセスするために必要 protected function onClickBtnStartOAuth2():void { swv = new StageWebView(); swv.addEventListener(Event.COMPLETE, onCompleteSWV); function onCompleteSWV(evt:Event):void { const codeSubstringKey:String = "code="; var title:String = swv.title; //「code」はタイトルに含まれている trace("onCompleteSWV() title=[" + title + "]"); var idx:int = title.indexOf(codeSubstringKey); if (idx != -1) { //「code」を切り出し code = title.substring(idx + codeSubstringKey.length); trace("onCompleteSWV() code=[" + code + "]"); //codeを元にaccessTokenをリクエスト(grant_typeはInstalledAppの場合はこれで固定) getAccessToken.send({"code":code, "client_id":CLIENT_ID, "client_secret":CLIENT_SECRET, "redirect_uri":REDIRECT_URI, "grant_type":"authorization_code"}); } } swv.stage = stage; //WebView表示開始(WebViewはディスプレイリストに追加できないのでフルスクリーンになる) swv.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); swv.loadURL(createAuthURL()); //許可ページリクエスト } protected function createAuthURL():String { var url:String = "https://accounts.google.com/o/oauth2/auth?" //ここに投げることになってる + "scope=" + escapeMultiByte("https://www.googleapis.com/auth/adsense.readonly") //許可を得たいサービス + "&redirect_uri=" + REDIRECT_URI + "&response_type=code" //InstalledAppだとこの値で固定 + "&client_id=" + CLIENT_ID return url; } protected function onResultGetAccessToken(evt:ResultEvent):void { var result:String = getAccessToken.lastResult as String; taAccessToken.text = result; trace("onResultGetAccessToken():" + evt + "\n" + result); var json:Object = JSON.parse(result); //JSONをパース accessToken = json.access_token; trace("onResultGetAccessToken():access_token=" + accessToken); swv.stage = null; //WebViewを非表示にする } protected function onFaultGetAccessToken(evt:FaultEvent):void { trace("onResultGetAccessToken():" + evt); } protected var startDate:String = "2012-01-01"; protected var endDate:String = "2012-01-31"; protected var dimension:String = "DATE"; protected var metric:String = "EARNINGS"; public function requestReportsGen():void { trace("requestReportsGen()"); reportsGen.send({"startDate":startDate, "endDate":endDate, "dimension":dimension, "metric":metric, "key":API_KEY, "access_token":accessToken}); } public function onResultReportsGen(evt:ResultEvent):void { var result:String = reportsGen.lastResult as String; trace("onResultReportsGen():" + evt + "\n" + result); taReportsGen.text = result; } public function onFaultReportsGen(evt:FaultEvent):void { trace("onFaultReportsGen():" + evt); } ]]> </fx:Script> <!-- UI部 --> <s:VGroup width="100%" height="100%" horizontalAlign="center" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"> <s:HGroup width="100%" verticalAlign="middle"> <s:Label text="code" width="125" fontSize="18"/> <s:Label width="100%" text="{code}"/> </s:HGroup> <s:TextArea id="taAccessToken" width="100%" height="100%" editable="false"/> <s:HGroup width="100%" verticalAlign="middle"> <s:Label text="accessToken" width="125" fontSize="18"/> <s:Label width="100%" text="{accessToken}"/> </s:HGroup> <s:Button enabled="{accessToken == null}" label="Start OAuth2" click="onClickBtnStartOAuth2();"/> <s:TextArea id="taReportsGen" width="100%" height="100%" editable="false"/> <s:Button enabled="{accessToken != null}" label="Request reports.generate" click="requestReportsGen();"/> </s:VGroup> </s:WindowedApplication>
以上、終了!うぃーあうちょ〜!
コメント
コメントを投稿