OAuth APIのproxyを作ってみました。生のリクエストに署名してAPIに転送し、結果を返します。
login.cgi
#!/usr/bin/perl -T use strict; use warnings; use CGI; use CGI::Session; use OAuth::Lite::Consumer; my %oauth_config = ( consumer_key => '_____________________', consumer_secret => '_________________________________________', request_token_path => 'https://api.twitter.com/oauth/request_token', authorize_path => 'https://api.twitter.com/oauth/authorize', access_token_path => 'https://api.twitter.com/oauth/access_token', ); my $cgi = new CGI; my $ua = new OAuth::Lite::Consumer(%oauth_config); my $session = new CGI::Session(undef, $cgi, {Directory=>'/tmp/session'}); if ($cgi->request_method eq 'POST') { my $request_token = $ua->get_request_token(callback_url => $cgi->url); $session->param(request_token=>$request_token); my $url = $ua->url_to_authorize(token => $request_token); print $session->header(-status=>302, -location=>$url); } elsif ($cgi->request_method eq 'GET') { my $access_token = $ua->get_access_token( token => $session->param('request_token'), verifier => $cgi->param('oauth_verifier')); $session->param(access_token=>$access_token); print $session->header(-status=>302, -location=>'./'); } else { print $session->header(-status=>405); }
OAuthの認証シーケンスを実行し、アクセストークンをセッションに保存します。セッション管理にはCGI::Sessionを使っています。
proxy.cgi
#!/usr/bin/perl -T use strict; use warnings; use CGI; use CGI::Session; use OAuth::Lite::Consumer; my %oauth_config = ( consumer_key => '_____________________', consumer_secret => '_________________________________________', ); my $api_base_url = 'http://api.twitter.com/1'; my $cgi = new CGI; my $ua = new OAuth::Lite::Consumer(%oauth_config); my $session = new CGI::Session(undef, $cgi, {Directory=>'/tmp/session'}); my $access_token = $session->param('access_token'); my %params = map { my @value = $cgi->param($_); $_ => \@value } $cgi->param; my $response = $ua->request( method => $cgi->request_method, url => $api_base_url.$cgi->path_info, params => \%params, token => $access_token, ); print $session->header( -status => $response->code, -type => $response->header('Content-Type'), ), ($response->decoded_content || $response->content);
login.cgi がセッションに保存したアクセストークンを使ってリクエストに署名します。転送先は $api_base_url + PATH_INFO です。
こちらもTwitter API(1.0)のURLになっていますが、%oauth_config と $api_base_url を修正すれば、他のサイトでも動くと思います。
index.html
<html> <head> <title>OAuth Proxy</title> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script> $(function(){ $.getJSON("proxy.cgi/account/verify_credentials.json", function(user){ $("#icon").attr("src", user.profile_image_url); $("#name").text(user.screen_name); $("#login").hide(); $("#contents").show(); }); }); </script> </head> <body> <div id="login"> <form method="POST" action="login.cgi"> <input type="submit" value="LOGIN" /> </form> </div> <div id="contents" style="display: none;"> <img id="icon"> <span id="name"></span> <ul> <li><a href="proxy.cgi/account/verify_credentials.xml"> account/verify_credentials</a></li> </ul> <ul> <li><a href="proxy.cgi/statuses/home_timeline.xml"> statuses/home_timeline</a></li> <li><a href="proxy.cgi/statuses/mentions.xml"> statuses/mentions</a></li> <li><a href="proxy.cgi/direct_messages.xml"> direct_messages</a></li> </ul> <form method='POST' action="proxy.cgi/statuses/update.xml"> <textarea name="status" cols="40" rows="3"></textarea> <div><input type="submit" value="Tweet" /></div> </form> </div> </body> </html>
認証前はLOGINボタンを表示し、認証後はユーザの情報とAPIへのリンクを表示します。
ちょっとだけAjaxを使ってみました。それからAPIのリンクはJSONではなくXMLの方にしました。そうしないと表示を見ても理解不能なので。*2
Cookieのpathとかはかなりいい加減ですが、ちゃんと直してmod_perlで動くようにすればある程度実用になるんじゃないかなあ。Twitterアプリを書いてみようかな。*3