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 は私にしか使えません