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は無効です。