PHPでGoogle Apps APIにClientLogin接続して情報を取得する

この記事は次のブログに引っ越しました。

このページでは、PHP5とZend_Gdataクラスを使って、GoogleAppsのサービス(GoogleAPI)を自分のWEBサービスで使うための基本的な情報をまとめています。 (※動作確認サーバ:chicappa!, xrea, lolipop, sakura) まとめと言っても、いささか冗長的で長いので、 GoogleAppsの各種APIにアクセスするためのオブジェクトを作るタイミングで、ログイン認証済みのデータを持ったオブジェクトを引数に渡して、出来上がったアクセス用オブジェクトのメソッドを使えば、GoogleAPIのあんな事やこんな事ができる。 それが分かっていて、GDataもClientLoginの意味もわかっているので、「ぶっちゃけ、ルーク、ソースが見たいの」って方は、サンプル・ソースへジャンプしてください。 ケイノスはメキシ漢(メキシコ人)なので、ビール片手にゆっくり付き合うんだヨーダって方は、お手すきにご覧ください。てへっ。 ※2015/03/16 追記 GoogleはGDataによるAPIのやりとりをやめたようです。記事は古い情報ですが、基本概念を知る手助けにはまだ有効だと思います。 GDataって何?Google Data Protocolって? GoogleAppsに自分のPHPアプリなどからアクセスしたいなぁと思うと、必ずGDataやGoogle Data ProtocolもしくはGoogle Data APIといった言葉にぶつかります。そして、わかりづらい。 順番に紐解いていくとして、まず「GData」から言うと、CSV, JSON, XMLなどと同じようなテキスト・データのフォーマットの一種です。CSVはフォーマットであってサービス名でないのと同じく、GDataというサービスがあるわけはありません。 例えば、とあるURLにデータをPOSTするとJSON形式で結果(データ)を受信できるサービスがあります。これは「うちのサービスにリクエストしたらHTMLじゃなくてJSON形式で結果を表示するから、勝手にテキスト・データを処理してね」といった意味なのですが、Google Data APIの場合は「うち(Google)のサービスにリクエストしたらGData形式で結果を返すよ」というだけです。 さらに言ってしまうと、「ぶっちゃけ、ただのRSSっぽいXMLデータなんだけど、俺様フォーマットで作ったものをGDataって呼んでいて、GData形式でPOSTしてくれれば、しかるべき処理もできるし、その結果もGDataで返しますよん。でも、やっぱり、ただのRSSっぽいXMLデータなので、今後はPOSTするルールやデータの書式もひっくるめて、Google Data Protocolと呼ぶので、よろしく」というものです。 そうです、Google Data Protocolにそって書かれたXMLのことを昔はGDataと呼んでいたのです。時代と共に、名称が二転三転して(整理されて)いくのですが、リファレンスの更新が追いついていないのです。 また、後で説明するZend社のGoogle用のクラス群がZend_Gdataクラスと呼ばれるので、これらがリファレンスをさらに分かりづらくする原因の1つでもあります。 ■小まとめ GData = Google Data Protocolに従ったXMLデータ 一方、Google Data APIは「Google Data(を使う)API」つまり先の「GDataを使って利用できる、GoogleのWEB APIサービスの総称」という意味です。(Google Data APIを使ったサービス一覧) なのに なぜドキュメントを読んでも素直に納得できないのでしょう。 昨今、色々なデータ形式がある中、GDataはGoogleいち押しの形式なのでリファレンス・サイトを見ても「GData形式、マジ便利だから。うち(Google)のサービス、全部GDataでやってるし、絶対メジャーになるから」とプッシュしまくりで、何かの勧誘のようで、かえって怪しい、と本能が語るのと似ている気がします。 しかも、そのGData形式でやり取りする際のルールを調べると、セキュリティの話も絡んできて、さらに複雑に感じさせるのです。 くどいようですが、GDataは、ただのXMLデータ形式です。そして、XMLデータをPOSTすると、XMLデータで処理結果が返ってくるAPI作ったよ、ということなのです。 ※追記 2015/03/16 現在 GoogleはGDataによるAPIのやりとりをやめたようです。 https://developers.google.com/gdata/ ちょっとプロトコる Googleのリファレンスの中の人たちは英語が堪能なので、あちこちで「英語でならニュアンスがわかるけど、日本語だと説明が面倒だからカタカナにしちまえ」的な箇所が見受けられます。これがルー大柴さん的なカタカナの使い方ならいいのですが。 さて、Googleのリファレンスを見る際に、一つ理解しておくと便利な単語が「プロトコル」です。 プロトルコ。いや、失礼、プロトコル。インターネットでは、TCP/IPなど、あちこちで聞かれる単語ですが、「インターネット通信の規格のこと」として理解していると「???」と感じる事があるようです。 この記事を読まれている方で、映画スターウォーズを「英語で」観られた方はいらっしゃるでしょうか。 金色のパントマイマー「C3PO」が、「私は600万を越す宇宙言語や暗号、各種族の儀礼に精通しております」のセリフで、実は「宇宙言語や暗号、各種族の儀礼」のところは英語で「プロトコル」の一語で済ましています。 また、FBI映画や軍隊映画、特に「24」などの組織系の映画で、「想定外の行為」に対して上司が融通をなかなか聞いてくれない場面で「It's a protocol!」(訳:だってルールなんだもん!)とよく怒鳴っていると思いませんか? そうすると、「プロトコル」の意味は「言葉?ルール?マナー?」とわからなくなりがちですが、噛み砕いて言うと「AとBが円滑に何かを行うための共通ルール」です。 言葉が通じない者同士なので、共通言語は英語にしましょう 今回のパラレル通信はACKインサイドで 今回の葬儀は、浄土真宗式で行いますので、なむあみだぶを4回 一呼吸置いてさらに4回 最後に2回なむあみだぶつをご唱和ください といった、関係者同士のルールのことを「プロトコル」と言うわけです。 では、下記がGoogleDataAPIのサイトの最初の文書です。 Google DATA API では、Web 上のデータを読み書きするシンプルな標準プロトコルを提供します。 つまり「データを読み書きするルールをGoogleが作ったので、GoogleAPI使うなら基本です」と言っているだけなのです。 より、イメージが湧くように、いくつかプロトコルのサンプルを上げてみましょう。 「ジャイアン・プロトコル」 「お前のモノは 俺のモノ」と来たら、、、 「俺のモノも 俺のモノ」 「ダチョウ倶楽部・プロトコル」 「俺は絶対やらないぞ!」(Aさん) 「お前やらないの?じゃあ俺がやるよ!」(Bさん) 「いやここは俺がやるよ!」(Cさん) 「・・・じゃあ俺がやるよ。」(Aさん) と来たら、、、 「どうぞどうぞ!」(Bさん&Cさん) つまり「プロトコル」とは、知らない人はチンプンカンプン、知っておかないと楽しめない(仲間になれない)「お約束」なので、面倒くせぇと感じても、付き合う以上は覚えないと仕方のないものだと思って下さい。 GoogleApps APIを使う基本 これも色々な資料を見ても、やっぱりわかりづらい。 Google AppsAPIリファレンス・サイトを覗きに行くと、一見シンプルなためハンズに行った時のような「なんかスゲェことできそう!」といった期待感があるのですが、いざ探しはじめるとドンキーのような煩雑さを感じるのは私だけでしょうか。いささかイラっとさえします。 まぁ、なかなか本題に入らないこの記事にもイラっと来るかもしれませんが、アチキも、ちょっと色々吐き出したいので、そこは我慢してちょ。 さて、GoogleAppsAPIを使うには、まずは「自分のWEBアプリがGoogleからのアクセス許可証をもらってからでないと各種APIのサービスを使えない」と考えるとシンプルです。 アクセス許可証といってもログインするだけなのですが、そのログイン行為を「HTTP認証トークンを取得する」といった面倒な言い方をします。トークンを取得するというのは、ログインしたことを証明する使い捨てのパスポートを作るようなものです。ビザでもいいのかな? アプリでのログイン成功後、そのHTTP認証トークンなるパスポートを使って GoogleApps の GoogleCalendar や GoogleSpreadsheet などの各種APIサービスにアクセスするわけです。 Basic認証のように一度パスワードが通ればセッションが有効な間は自由にアクセスできる方法は、一度入場するとアトラクションがすべてタダの 昔ながらの遊園地だとすると、API、つまりサービスを利用するたびに、取得した「HTTP認証トークン」見せる必要がある方法は、ディズニーランドのような、アトラクションごとにパスポートを見せないといけない遊園地の仕組みに変わったみたいなもんでしょうか。わかりづらいか。 では、その「GoogleAppsAPIサービスにアクセスして使うにはどうするか」というと、基本的にXMLデータをGoogleのルールに従ってPOST(送信)して、表示(受信)されたXMLデータをWEBアプリ側で解析して処理します。 つまり、認証からデータ取得やデータ操作までをGoogle Data Protocol(Googleのルール)にそって行うわけです。 確かに、PHP以外にJavascriptや他の言語でも開発が必要な場合は、このプロトコルについての知識を深く掘り下げる必要がありますが、どの言語で開発してもWebAPI自体は同じものです。 そこで、この分かりづらいGoogleAppsの各種サービス(API)に、シンプルにアクセスさせるための便利なクラスを先人の方々が作られたので、それを使います。その便利なクラス群の1つが噂の「Zend_Gdata」です。 具体的には、使いたいサービスのクラスを選び、オブジェクト(インスタンス)を作ります。この時に、先程のログインを証明する使い捨てパスポート(HTTP認証トークン)を使って作成します。 無事オブジェクトが作成されると、そのサービスにアクセスされるので、そこからオブジェクトの関数(メソッド)を使ってデータを引き出すわけです。 ■データを引き出す例 下記、例はGoogleCalendarの一覧をオブジェクトの"getCalendarListFeed"メソッドを使って取得する例です。 $oServiceは、後記する認証トークン(ここで言うパスポート)を使って作られたGoogleCalendarのオブジェクトです。 $oListFeed= $oService->getCalendarListFeed(); これだけでデータが引き出せます。つまり、認証トークンを使ってオブジェクトを作ってしまうところまで出来てしまえば後は いささか簡単なんです。 GoogleAppsAPIにアクセスする際の認証方法の種類 先に述べたように、Google Apps APIを使うには、まずはサーバ(あなたのスクリプト)がログインする必要があるのですが、そのログインを証明する使い捨てパスポート(HTTP認証トークン)を取得するのに大きく2種類あります。 認証方法名 概要 ClientLogin パスワードなどをアプリ側に含めて認証する方法。実装は楽だが注意が必要。 Authsub パスワードなどをユーザーが入力して認証する方法。安心だが実装はいささか面倒。 このページではClientLoginを使った情報を記載します。 注意点としては、WEBアプリケーションで使う場合はClientLoginによる認証は推奨されていません。サーバーのスクリプトにパスワードなどを記述するからです。 ただ、ぶっちゃけどちらの方法でも、HTTP認証トークンさえ取得できれば(認証済みのオブジェクトさえ作成できれば)動くので、まずは実装が楽なClientLoginで大枠の仕組みをつかむのがいいと思います。 概要を把握したら、AuthSubでHttpクライアントの認証トークンを取得する方法に進んではいかがでしょう。 ※関連URL:Zend_GDataによるClientLoginの詳細 ※参考URL:AuthSub認証を使う前に、アプリのURLを登録してもらう必要があります ■ClientLoginによるHTTP認証オブジェクトのつくりかた(Google Spreadsheet編) <?php $sUser = "user@mail.com"; //GoogleApps OR GoogleAccountのメアド $sPass = "p@ssw0rd"; //上記メアドのログインパスワード //HTTP認証オブジェクトの作成 $sAuthServiceName = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME; $oHttpClient = Zend_Gdata_ClientLogin::getHttpClient($sUser, $sPass , $sAuthServiceName); //GoogleAppsのサービス(API)を利用するオブジェクトの作成 $oService = new Zend_Gdata_Spreadsheets($oHttpClient ); ?> 上記を見てもらうと、ログイン名とパスワードをオブジェクト作成時に渡しています。つまり、ログイン行為をPHPでしているわけです。 無事、ログインできると「使い捨のパスポート」的なものがGoogleから発行されるので、以後、GoogleAPIのサービスを利用するには、この使い捨てパスポート($oServiceのオブジェクト)を使って行います。 AuthSubログインの場合は、使い捨てパスポートを、アプリ内に記述するのではなく、ユーザーをGoogleのログイン画面に飛ばして取得させているわけです。 くどいようですが、APIのサービスを利用するには、アプリ内にログイン情報を記載するか、ユーザーにログイン画面でログインさせる、どちらの方法でも、Googleから認証を受けた「クライアント」オブジェクトさえ出来てしまえばいいのです。 GoogleAppsでのClientLoginの主な流れ ログイン情報を引数にインスタンス(認証オブジェクト)を作成し認証トークンを取得する。 作成されたオブジェクトでGoogleAppsのサービスのインスタンスを作成。 サービスのオブジェクトを使って色々する。 GoogleAppsに限らず通常のGoogleAccountでも認証する工程は基本的に同じです。 実は、ステップ1のオブジェクトを作成する際の9番目の引数が'HOSTED'の場合GoogleAppsのアカウントで認証となり、"GOOGLE"の場合はGoogleAccountの認証となります。 ちなみに、GoogleAppsGoogleアカウントの両方に対応させたい場合は'HOSTED_OR_GOOGLE'になるのですが、実はこれがデフォルトなので、安心してGoogleAppsのメアドで認証できます。[詳細] さて、ここまでお付き合いいただいた上で、他の方のソースを感じてみてください。→「PHPアプリケーションをGoogleContactsと統合する」 ■PHPとZend_GDataでGoogleAppsのカレンダー情報を取得するサンプル ※関連サンプル:PHPからGoogleAppsGoogle SpreadsheetsをDBとして利用する (より具体的なプログラムを見たい方) <?php require_once 'Zend/Gdata/ClientLogin.php'; require_once 'Zend/Gdata/Calendar.php'; /** * ClietLogin認証 */ // ログインアカウントの情報 $sEmail = 'username@your-hosted-google-apps.com'; $sPasswd = 'pa$$word'; $sServiceName = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; // ClientLoginのインスタンス(HTTPクライアント認証オブジェクト)を作成します $oHttpClient = Zend_Gdata_ClientLogin::getHttpClient($sEmail, $sPasswd, $sServiceName); /** * Google Calendar接続 */ // HTTPクライアント認証オブジェクトを使って、Calendar サービスのインスタンスを作成します $oService = new Zend_Gdata_Calendar($oHttpClient); // Google Calendarの情報を取得します $oListFeed= $oService->getCalendarListFeed(); /** * 表示 */ echo "<pre>"; print_r($oListFeed); echo "</pre>"; ?> ※参考ページ:Zend Framework: Documentation getHttpClientメソッドの引数 Zend_Gdata_ClientLogin::getHttpClientの引数 function getHttpClient( $email, $password, $serviceName = 'xapi', $client = null, $source = self::DEFAULT_SOURCE, $loginToken = null, $loginCaptcha = null, $loginUri = self::CLIENTLOGIN_URI, $accountType = 'HOSTED_OR_GOOGLE' ){...} 引数 型 省略時の値 用途 $email string (必須) Googleアカウント,GoogleAppsのEmailアドレス $password string (必須) パスワード $serviceName string xapi サービス名(xapiは汎用サービス。カレンダーの場合は'cl'など。) $client Zend_Gdata_HttpClient object null HTTPクライアントオブジェクト $source string Zend-ZendFramework IDとなるアプリの名前 $loginToken string nullログイン時にサーバが返すトークン $loginCaptcha string null ログイン時にサーバが返すCAPTCHAのチャレンジ文字列 $loginUri string https://www.google.com/accounts/ClientLogin リクエスト先URL $accountType string HOSTED_OR_GOOGLE 認証先のサービスのタイプ。GoogleアカウントかGoogleAppsか 参考ページ:ClientLogin in the Google Data Protocol Client Libraries - Google Data Protocol - Google Code