Created
December 23, 2012 07:21
-
-
Save zigorou/4362452 to your computer and use it in GitHub Desktop.
Facebook login sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
use Config::Pit; | |
use Data::Section::Simple qw(get_data_section); | |
use HTTP::Request; | |
use HTTP::Status qw(:constants); | |
use Log::Minimal; | |
use LWP::UserAgent; | |
use Plack::Builder; | |
use Plack::Request; | |
use Plack::Response; | |
use Plack::Session; | |
use String::Random qw(random_regex); | |
use Text::Xslate; | |
use URI; | |
use URI::QueryParam; | |
use URI::Template; | |
# https://developers.facebook.com/docs/howtos/login/server-side-login/ | |
my $tx = Text::Xslate->new( syntax => "TTerse" ); | |
my $ua = LWP::UserAgent->new; | |
my $authorize_uri_template = URI::Template->new( | |
"https://www.facebook.com/dialog/oauth{?client_id,redirect_uri,state}" | |
); | |
my $access_token_uri_template = URI::Template->new( | |
"https://graph.facebook.com/oauth/access_token{?client_id,client_secret,redirect_uri,code}" | |
); | |
my $redirect_uri = "http://localhost:5000/"; | |
my $credentials = pit_get("facebook_test", require => +{ | |
id => "Facebook App ID", | |
secret => "Facebook App Secret", | |
}); | |
sub render { | |
my ($res, $section_name, $vars) = @_; | |
$res->content($tx->render_string(get_data_section($section_name), $vars)); | |
} | |
my $app = sub { | |
my $env = shift; | |
my $req = Plack::Request->new($env); | |
my $res = Plack::Response->new( | |
HTTP_OK, | |
[ "Content-Type" => "text/html" ] | |
); | |
if ($req->path_info eq "/favicon.ico") { | |
$res->code(HTTP_NOT_FOUND); | |
return $res->finalize; | |
} | |
my $session = Plack::Session->new($env); | |
if ($req->param("code")) { | |
my $code = $req->param("code"); | |
my $state = $session->get("state") || ""; | |
unless ($state && $state eq $req->param("state")) { | |
warnf("Invalid state (expect: %s. actual: %s)", $state, $req->param("state")); | |
render($res, "error.html", +{ error => "Invalid state" }); | |
} | |
else { | |
my $access_token_url = $access_token_uri_template->process_to_string( | |
client_id => $credentials->{id}, | |
client_secret => $credentials->{secret}, | |
code => $code, | |
redirect_uri => $redirect_uri, | |
); | |
infof("Access token url (url: %s)", $access_token_url); | |
my $request = HTTP::Request->new( GET => $access_token_url ); | |
my $response = $ua->request( $request ); | |
unless ($response->is_success) { | |
render($res, "error.html", +{ error => $response->status_line }); | |
} | |
else { | |
my $query = URI->new("", "http"); | |
$query->query($response->content); | |
render($res, "view_access_token.html", +{ access_token => $query->query_param("access_token") }); | |
} | |
} | |
} | |
elsif ($req->param("error")) { | |
render($res, "error.html", +{ error => $req->param("error") }); | |
} | |
else { | |
my $state = random_regex(q|[A-Za-z0-9]{24,32}|); | |
infof("Generated state (state: %s)", $state); | |
$session->remove("state"); | |
$session->set("state", $state); | |
my $authorize_url = $authorize_uri_template->process_to_string( | |
client_id => $credentials->{id}, | |
redirect_uri => $redirect_uri, | |
state => $state, | |
); | |
infof("Authorize url (url: %s)", $authorize_url); | |
render($res, "login.html", +{ authorize_url => $authorize_url }); | |
} | |
$res->finalize; | |
}; | |
builder { | |
enable "Session"; | |
$app; | |
}; | |
__DATA__ | |
@@ login.html | |
<html> | |
<head> | |
<title>Login with facebook</title> | |
</head> | |
<body> | |
<a href="[% authorize_url | html %]">Login with facebook</a> | |
</body> | |
</html> | |
@@ error.html | |
<html> | |
<head> | |
<title>Login error</title> | |
</head> | |
<body> | |
<dl> | |
<dt>error<dt> | |
<dd>[% error | html %]</dd> | |
</dl> | |
</body> | |
</html> | |
@@ view_access_token.html | |
<html> | |
<head> | |
<title>Login success</title> | |
</head> | |
<body> | |
<dl> | |
<dt>access token</dt> | |
<dd>[% access_token | html %]</dd> | |
</dl> | |
<p> | |
Please execute following commands | |
</p> | |
<pre> | |
lwp-request -m GET -H "Authorization: Bearer [% access_token | html %]" https://graph.facebook.com/me | json_xs -t json-pretty | |
</pre> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Config::Pit で事前に自分で作った AppID, AppSecret を突っ込んでおく必要があります。
あとは LWP, JSON::XS に付属のコマンドがあるとばちーんと Graph API を実行する事が出来ます。