Google Analytics の集計データを Google API で取得して、人気記事のランキングを生成していたのですが、利用していた認証の仕組みが先日からいよいよ停止されて使えなくなってしまいました。「この認証方式はいずれ廃止されるから早めに OAuth 認証に移行してね♥」とアナウンスされていたまま「OAuth とかめんどくせー」と放置していたツケですね(;´Д`) OAuth 認証については、クライアント向けのライブラリを利用すれば簡単らしいのですが、生 Perl で Google API を叩けるようになるまで勉強も兼ねて色々調べてみました。
初めに、Google Developer Console から、アプリケーションの登録を行います。登録手順の詳細などは以下のリンクを参考に。ここでは、新しいクライアント ID を生成する際に、"インストールされているアプリケーション"を選択して、クライアント ID、クライアント シークレット、リダイレクト URI の3つのパラメータを控えておきます。
下記のコードを実行すると、https://accounts.google.com/o/oauth2/auth?... から始まる URL が表示されるので、URL 文字列をコピーして Web ブラウザで開きます。Google アカウントでログインすると、このアプリケーションが Google Analytics のデータを表示しても良いか尋ねてくるので承認します。
### Developer Console から控えておいたクライアント ID、クライアント シークレット、リダイレクト URI my %client = ( client_id => '123456789012-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', client_secret => 'HogeFugaPiyoHogeFugaPiyo', redirect_uri => 'urn:ietf:wg:oauth:2.0:oob', ); use URI::Escape; my %param = ( response_type => 'code', client_id => $client{client_id}, redirect_uri => $client{redirect_uri}, # @see https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization scope => 'https://www.googleapis.com/auth/analytics.readonly', ); my $url = 'https://accounts.google.com/o/oauth2/auth?'. # auth_uri join '&', map { uri_escape($_). '='. uri_escape($param{$_}) } keys %param; print $url;
承認すると、次のような画面に切り替わるので、認証コードをコピーして次に進みます。
Step 1. で取得した認証コードを使ってトークンを取得します。
### ここは step1.pl と同じ my %client = ( ... ); use LWP::UserAgent; my %param = ( code => 'AUTHENTICATION_CODE', # Step 1. で取得した認証コード client_id => $client{client_id}, client_secret => $client{client_secret}, redirect_uri => $client{redirect_uri}, grant_type => 'authorization_code', ); my $ua = LWP::UserAgent->new or die; my $res = $ua->post( # POST 'https://accounts.google.com/o/oauth2/token', # token_uri \%param ) or die; $res->is_success or die $res->status_line; print $res->content;
リクエストが成功すると、次のような JSON データが返ってきます。
{ "access_token" : "XXXXXXXX_ACCESS_TOKEN_XXXXXXXX", "token_type" : "Bearer", "expires_in" : 3600, "refresh_token" : "XXXXXXXX_REFRESH_TOKEN_XXXXXXXX" }
Step 1. で取得した AUTHENTICATION_CODE
は、上記のスクリプトを実行するたびに失効するので、実験などでトークンを度々取得するには、その都度、認証コードを取得しなければなりません。
Google API にアクセスする時には、この access_token
が必要になりますが、expires_in
で示された期限後(単位は秒)には有効期限が切れてしまいます。そこで、refresh_token
を利用して access_token
を取得しなおします。
### ここは step1.pl と同じ my %client = ( ... ); use LWP::UserAgent; my %param = ( refresh_token => 'XXXXXXXX_REFRESH_TOKEN_XXXXXXXX', client_id => $client{client_id}, client_secret => $client{client_secret}, grant_type => 'refresh_token', ); my $ua = LWP::UserAgent->new or die; my $res = $ua->post( 'https://accounts.google.com/o/oauth2/token', # token_uri \%param ) or die; $res->is_success or die $res->status_line; print $res->content;
リクエストが成功すると、次のような JSON データが返ってきます。
{ "access_token" : "XXXXXXXX_NEW_ACCESS_TOKEN_XXXXXXXX", "token_type" : "Bearer", "expires_in" : 3600, }
例えば、Google Analytics で使える API から、ウェブサイトの Page View 数を取得するには、先ほど取得した access_token
をくっ付けて、次のような URL にアクセスします*1。
https://www.googleapis.com/analytics/v3/data/ga?ids=ga%3A3857126&start-date=2015-05-01&end-date=2015-05-31&metrics=ga%3Apageviews&access_token=XXXXXXXX_ACCESS_TOKEN_XXXXXXXX
試しに、めちゃくちゃな access_token
に書き換えてみると、エラーが返ってくるのが判ります。
access_token
を付けてリクエストを行うrefresh_token
を用いて access_token
を取得できるrefresh_token
は何度でも/いつまでも使えるrefresh_token
を取得して設定ファイルなどに書き出しておけば、以降は access_token
を簡単に取得できるaccess_token
を与えたとしても、この URL は私にしか使えません