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>
以上、終了!うぃーあうちょ〜!


コメント
コメントを投稿