tokuhirom's Blog

Amon2::Auth によるロケタッチAPIをつかったサイトの構築 〜 軽量フレームワークAmon2入門 (6) 〜

https://github.com/tokuhirom/TouchTouch/commit/dbb3cdeacf6629dc8213bd9fa50e14f9712634b9

久々に Amon2 入門だ! 最近リリースされたばかりの Amon2::Auth モジュールをつかってみよう!

Amon2::Plugin::Web::Auth への依存を Makefile.PL に設定する!!

diff --git a/Makefile.PL b/Makefile.PL
index f8b9297..8f0f183 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -20,6 +20,7 @@ WriteMakefile(
         'Test::WWW::Mechanize::PSGI'                         => '0',
         'JSON'                         => '2.50',
         'Plack::Middleware::Session'                         => '0',
+               'Amon2::Plugin::Web::Auth' => 0,
     },
     MIN_PERL_VERSION => '5.008001',
     (-d 'xt' and $ENV{AUTOMATED_TESTING} || $ENV{RELEASE_TESTING}) ? (

config/development.pl に設定をかく! 実際にはサイト上で取得した client id と client secret を設定する! redirect_uri は実際の URL だっ !! 具体的には "http://localhost:5000/auth/loctouch/callback" などになるだろう!

diff --git a/config/development.pl b/config/development.pl
index dc91780..f95b200 100644
--- a/config/development.pl
+++ b/config/development.pl
@@ -16,4 +16,11 @@ if ( -d '/home/dotcloud/') {
             sqlite_unicode => 1,
         }
     ],
+    Auth => {
+        Loctouch => {
+            client_id => die,
+            client_secret => die,
+            redirect_uri => die,
+        }
+    }
 };

そして plugin をロードするんだ!やってることは簡単だから解説はいらないだろう!

diff --git a/lib/TouchTouch/Web.pm b/lib/TouchTouch/Web.pm
index dea48fd..33acdd6 100644
--- a/lib/TouchTouch/Web.pm
+++ b/lib/TouchTouch/Web.pm
@@ -11,6 +11,23 @@ sub dispatch {
     return TouchTouch::Web::Dispatcher->dispatch($_[0]) or die "response is not
 }
 
+__PACKAGE__->load_plugin(
+    'Web::Auth',
+    {
+        module      => 'Loctouch',
+        on_finished => sub {
+            my ( $c, $token, $user ) = @_;
+            $c->session->set( 'user' => $user );
+            $c->session->set( 'token' => $token );
+            return $c->redirect('/');
+        }
+    }
+);
+
+sub user { $_[0]->session->get('user') }
+sub token { $_[0]->session->get('token') }
+
+
 # setup view class
 use Text::Xslate;
 {

あとは、とってきたトークンをつかうだけだ! LWP + JSON で処理するシンプルなコードだ!

package TouchTouch::Web::Dispatcher;
use strict;
use warnings;
use utf8;
use Amon2::Web::Dispatcher::Lite;
use LWP::UserAgent;
use JSON qw(decode_json);

any '/' => sub {
    my ($c) = @_;
    my $stickers;
    if ($c->user) { # loggedin
        my $url = 'https://api.loctouch.com/v1/users/@self/stickers';
        my $ua = LWP::UserAgent->new();
        my $res = $ua->get($url . '?oauth_token=' . $c->token);
        $res->is_success or die $res->status_line;
        $stickers = decode_json($res->decoded_content)->{stickers};
    }
    $c->render(
        'index.tt',
        {
            stickers => $stickers,
            min      => sub { $_[0] > $_[1] ? $_[1] : $_[0] }
        }
    );
};

post '/account/logout' => sub {
    my ($c) = @_;
    $c->session->expire();
    $c->redirect('/');
};

1;

HTML はこんな風にしてやってくれ! 認証のエンドポイントが /auth/loctouch/authenticate になってるところに注意!デフォルトの認証 URL のパスはこうなっているのだ!

[% WRAPPER 'include/layout.tt' %]

<section>

[% IF c().user %]
    Hi, [% c().user.display_name %]!
    <section>
    [% FOR v IN stickers %]
        <div style="font-size: [% min(100*(v.count*0.2), 200) | format('%d') %]%" class="clearfix">
            [% v.count %]
            [% v.name %]
            [% v.description %]
            [% v.key %]
        </div>
    [% END %]
    </section>
    <form method="post" action="/account/logout">
        <input type="submit" value="logout" class="btn primary" />
    </form>
[% ELSE %]
    <a href="/auth/loctouch/authenticate">login</a>
[% END %]

</section>

[% END %]

ちなみにこのサンプルアプリは、ロケタッチにおける自分のステッカーの一覧を表示するだけなのでなにもおもしろくないぞ!