OAuth :: 履歴を取得
OAUthを使ってAPIにアクセスすると、同じLong URLに対して毎回違ったShort URLを返してきます。とりあえず、履歴を見てみましょう…。なお、履歴を見るにはOAuthによる認証が必須です。
hisotry.cgi (OAuth必須)
#!/usr/bin/perl use LWP::UserAgent; use LWP::ConnCache; use Digest::HMAC_SHA1; use JSON; # API Key my $apikey = 'API key'; # OAuth Consumer Secret my $consumer_sec = 'OAuth Consumer Secret'; # OAuth Consumer Key my $consumer_key = 'OAuth Consumer Key'; # OAuth Access Token my $oauth_token = 'OAuth Access Token'; # OAuth Access Token Secret my $oauth_token_secret = 'OAuth Access Token Secret'; # Requestを送るURL my $url = 'https://www.googleapis.com/urlshortener/v1/url/history'; # Request Method my $method = 'GET'; # OAuth用パラメータ my %oauth_param; $oauth_param{oauth_token} = url_encode($oauth_token); $oauth_param{oauth_consumer_key} = $consumer_key; # 署名方法はHMAC-SHA1で。 $oauth_param{oauth_signature_method} = 'HMAC-SHA1'; # APIに渡すパラメータ my %query_param; $query_param{key} = $apikey; # #define STARTTOKEN my $STARTTOKEN = 'start-token', # Keep-alive 有効 my $ua = LWP::UserAgent->new; $ua->conn_cache(LWP::ConnCache->new); # 結果を格納 my $response = ''; for (my $nextPageToken = '';;) { # タイムスタンプとか $oauth_param{oauth_timestamp} = time(); $oauth_param{oauth_nonce} = int(rand(2**32)) . int(rand(2**32)); # 前のループで「次」があるといわれていれば、そこからスタート if ($nextPageToken) { $query_param{$STARTTOKEN} = url_encode($nextPageToken); } # Signature Base String の作成 my $signature_base = createSigBase($url, $method, \%oauth_param, \%query_param); # Token Secretを取得済なので、署名キーは # '<OAuth Consumer Secret>&<OAuth Token Secret>' my $signature_key = url_encode($consumer_sec) . '&' . url_encode($oauth_token_secret); # Signature Base String を、key で署名してURLエンコードして署名を作成 my $signature = url_encode(hmac_sha1($signature_key, $signature_base)); # Authorization: ヘッダ情報の生成 my $auth_param = createAuthParam(\%oauth_param, $signature); # APIにパラメータを渡すためにURLに連結 my $cur_url = $url; if (%query_param) { $cur_url .= '?' . createQueryParam(\%query_param); } # 不要なので消去 delete $query_param{$STARTTOKEN}; # 準備完了!リクエストの実行!! my $res = $ua->request( HTTP::Request->new( $method, $cur_url, HTTP::Headers->new( 'Authorization' => $auth_param ) ) ); # 結果をバッファ $response .= $res->content; my $result = decode_json($res->content); # 次はあるか? $nextPageToken = $result->{nextPageToken}; unless ($nextPageToken) { last; } } print "Content-type: application/json\n\n"; print $response; exit; # Signature Baseを作ります sub createSigBase { my ($url, $method, $ref_oauth_param, $ref_query_param) = @_; my %all_param = (%$ref_oauth_param, %$ref_query_param); # マージ my @sb = (); foreach my $k (sort(keys(%all_param))) { push(@sb, $k . '=' . $all_params{$k}); } my $param = join('&', @sb); return join('&', ($method, url_encode($url), url_encode($param))); } # Authorization: ヘッダの内容を作ります sub createAuthParam { my ($ref_oauth_param, $sig) = @_; my @op = (); while (my ($key, $value) = each(%$ref_oauth_param)) { push(@op, $key . '="' . $value . '"'); } push(@op, "oauth_signature=\"$sig\""); return 'OAuth ' . join(', ', @op); } # APIにパラメータを渡すためにURLに連結する準備 sub createQueryParam { my $ref_query_param = shift; my @qp = (); while (my ($k, $v) = each(%$ref_query_param)) { push(@qp, $k . '=' . $v); } return join('&', @qp); } # hmac_sha1 署名。 sub hmac_sha1 { my ($key, $msg) = @_;; return Digest::HMAC_SHA1->new($key)->add($msg)->b64digest . '='; } # URL エンコード # http://www.din.or.jp/~ohzaki/perl.htm#JP_Escape を参考にしました。 sub url_encode { $_ = shift; s/([^a-zA-Z0-9_.!~*'()-])/'%' . uc(unpack('H2', $1))/eg; return $_; } # URL デコード # http://www.din.or.jp/~ohzaki/perl.htm#JP_Escape を参考にしました。 # 今回は使いません… sub url_decode { $_ = shift; s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; return $_; }
2巡目からは、前の時のnextPageTokenをstart-tokenとしてURLに付加します。start-tokenとkeyはSignature Base Stringには入れる必要がありますが、Authorization:ヘッダには入れてはいけません!