Using Facebook Graph API with Perl
読んでおくべきドキュメント
Server Side Loginに関しては、まずはこの3つを読んでおけばよい。
https://developers.facebook.com/docs/concepts/login/login-architecture/
https://developers.facebook.com/docs/howtos/login/server-side-login/
https://developers.facebook.com/docs/reference/dialogs/oauth/
OAuth2のRFCも読んでおく。
Facebookで言うところのServer Side LoginがAuthorization Code Grantに当たる。
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI ---->| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Authorization Code ---------' | | Client | & Redirection URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token)
http://tools.ietf.org/html/rfc6749#section-4.1
Facebook Appをつくる
Facebook App Dashboardにて。 AppDomainとSiteURLはそれぞれlocalhost、http://localhost/でもOK。つまり、ローカルマシンでFacebook Graph APIを試すことができる。
Access Tokenを取得し、Graph APIを呼び出す
例えばAmon2::Liteを使うと、以下の通り。
#!/usr/env/perl use strict; use warnings; use utf8; use Amon2::Lite; use Config::Pit; use String::Random; use Furl; get '/' => sub { my $c = shift; my $pit = pit_get("www.facebook.com"); my $state = String::Random->new->randregex('\w{16}'); $c->redirect('https://www.facebook.com/dialog/oauth/', +{ client_id => $pit->{app_key}, redirect_uri => 'http://localhost:9000/facebook/callback', state => $state, }); }; get '/facebook/callback' => sub { my $c = shift; # TODO validate $c->req->param('state') my $pit = pit_get("www.facebook.com"); my $uri = URI->new('https://graph.facebook.com/oauth/access_token'); $uri->query_form( client_id => $pit->{app_key}, client_secret => $pit->{app_secret}, code => $c->req->param('code'), redirect_uri => 'http://localhost:9000/facebook/callback', ); # get access token my $furl = Furl->new(agent => 'Furl', timeout => 1); my $res = $furl->get($uri->as_string); if ( $res->status == 200 ) { my ($access_token, $expires) = split('&', $res->content); $access_token =~ s#^access_token=##; $expires =~ s#^expires=##; # Access to Graph API my $json = $furl->get("https://graph.facebook.com/me?access_token=$access_token")->content; return $c->create_response(200, [ 'Content-Type' => 'application/json' ], $json); } use Data::Dump qw(dump); $c->create_response(500, [ 'Content-Type' => 'text/plain' ], dump $res); }; __PACKAGE__->to_app();
実際にはstateの検証やsessionへのaccess_token保存なども必要になる。
まとめ
FacebookのServer Side LoginのサンプルをPerlで実装してみた。
OAuth2(Authorization Code Grant)はライブラリ使わなくても実装できるくらいシンプルなプロトコルだなと実感。