なんちゃって☆めも :: Google URL Shortener API であそ~ぶ

OAuth AuthorizeToken & GetAccessToken

GetRequestTokenで取得したTokenをAuthorizeします。
まずcallback.cgiを用意して、GetRequestTokenで指定したパスに配置します。先ほどメモったOAuth Token Secretを盛り込んでおきます。これ以外の違いは、CGIパラメータで受け取るoauth_tokenとoauth_verifierをAuthorizationヘッダに追加することくらいです。

callback.cgi

#!/usr/bin/perl

use LWP::UserAgent;
use Digest::HMAC_SHA1;
use CGI;

my $q = CGI->new;

# OAuth Consumer Secret
my $consumer_sec = 'OAuth Consumer Secret';

# OAuth Consumer Key
my $consumer_key = 'OAuth Consumer Key';

# OAuth Token Secret
my $oauth_token_secret = 'OAuth Token Secret';

# Requestを送るURL
my $url = 'https://www.google.com/accounts/OAuthGetAccessToken';

# URLへのMETHOD
my $method = 'GET';

# OAuth用パラメータ
my %oauth_param;
$oauth_param{oauth_consumer_key} = $consumer_key;
$oauth_param{oauth_callback} = $callback_url;

# 署名方法はHMAC-SHA1で。
$oauth_param{oauth_signature_method} = 'HMAC-SHA1';

# Scopeは、今回はURL Shortener
$oauth_param{scope} = 'https://www.googleapis.com/auth/urlshortener';

# oauth_tokenとoauth_verifierはCGIのパラメータで取得
# 本来は先ほど取得したOAuth Tokenと比較すべきなんでしょうが…。
$oauth_param{oauth_token} = url_encode($q->param('oauth_token'));
$oauth_param{oauth_verifier} = $q->param('oauth_verifier');

# タイムスタンプとか
$oauth_param{oauth_timestamp} = time();
$oauth_param{oauth_nonce} = int(rand(2**32)) . int(rand(2**32));

# Signature Base String の作成
my $signature_base = createSigBase($url, 'GET', \%oauth_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);

# 準備完了!リクエストの実行!!
my $res = LWP::UserAgent->new->request(
	HTTP::Request->new(
		$method,
		$url,
		HTTP::Headers->new('Authorization' => $auth_param)
	)
);

# method決め打ちなら…。
# my $res = LWP::UserAgent->new->get($url, 'Authorization' => $auth_param);

# 結果発表~
print "Content-type: text/plain\n\n";
foreach my $pair (split(/&/, $res->content)) {
	print url_decode($pair) . "\n";
}
# for Febug
# print $res->as_string; 

exit;

# この下は同じ~

# Signature Baseを作ります
sub createSigBase {
	my ($url, $method, $ref_oauth_param) = @_;
	my $param = '';
	{
		my @op = ();
		foreach my $k (sort(keys(%$ref_oauth_param))) {
			push(@op, $k . '=' . url_encode($ref_oauth_param->{$k}));
		}
		$param = join('&', @op);
	}
	return join('&', ($method, url_encode($url), url_encode($param)));
}

# Authorization: ヘッダの内容を作ります
sub createAuthParam {
	my ($ref_oauth_param, $sig) = @_;
	my @op = ();
	foreach my $k (keys(%$ref_oauth_param)) {
		push(@op, $k . '="' . $ref_oauth_param->{$k} . '"');
	}
	push(@op, 'oauth_signature="' . $sig . '"');
	return 'OAuth ' . join(', ', @op);
}

# 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 $_;
}
準備できたらGetRequestTokenの時に指定したパスに配置して、パーミッションの設定などを忘れずに!

AuthorizeToken & GetAccessToken

GoogleのOAuth PlaygroundへGo!。
Choose your Scopeでは…
URL Shortener クリック!
Modify the OAuth Parametersでは…
oauth_signature_method
HMAC-SHA1 選択!
oauth_consumer_key
OAuth Consumer Key
consumer secret
OAuth Consumer Secret
oauth_token_secret
GetRequestTokenで得たoauth_token_secret
oauth_token
GetRequestTokenで得たoauth_token
"oauth_token_secret"と"oauth_token"の 入力順に注意! ちなみに、URLデコードしたものを入力します。GetRequestTokenのCGIはデコードして出力するのでそのままコピペでOKです。
準備できたら、Get a Request Token "Request"をクリック!右のほうのに"Bad Request"とか"signature_invalid"とか出ても、無視して Authorize the Request Token の "Authorize"をクリック!!
・・・すると、「サイト サイト名 は下記のサービスで使用するため Google アカウント へのアクセスをリクエストしています。」というようなページに遷移するので、"アクセスを許可"をクリック!!!
・・・すると、callback.cgiにリダイレクトされて、↓みたいなの返ってきたら成功!
oauth_token=hoge
oauth_token_secret=fuga
これがいわゆる Access Token です。今後ずっと使うんで、内容をメモっておいてください。なお、この段階で先ほどのRequestTokenとかSecretは無効です。