はてな認証APIをCatalystに組み込む
はてな認証APIをCatalystに組み込んでみます。びっくりするほど簡単です。
http://localhost:3000/をトップページとして、http://localhost:3000/loginにアクセスするとログイン、http://localhost:3000/logoutにアクセスするとログアウトするようにしてみます。
予め2018年10月31日(水) をもって、はてな認証APIの提供を終了します。それに伴い、OAuthへ移行をお願いいたします - はてなの日記 - 機能変更、お知らせなどでアプリケーションの登録をしておきます。コールバックURLにhttp://localhost:3000/auth_hatenaを指定しました。
いつものアレ
% catalyst.pl MyApp % ./script/myapp_create.pl view TT TT
lib/MyApp.pm
use Catalyst qw/-Debug ConfigLoader Static::Simple Authentication Authentication::Credential::Hatena Session Session::State::Cookie Session::Store::File /;
AuthenticationプラグインとSessionプラグインを追加します。Session::Store::*とかSession::State::*はお好みで。サンプルなのでFileとCookieを使いました。
myapp.yml
--- name: MyApp authentication: hatena: api_key: ***YOUR API_KEY*** secret: ***YOUR SECRET***
2018年10月31日(水) をもって、はてな認証APIの提供を終了します。それに伴い、OAuthへ移行をお願いいたします - はてなの日記 - 機能変更、お知らせなどで登録したアプリケーションのAPIキーと秘密鍵を設定します。
root/index
<html> <head><title>Auth API</title></head> <body> [% IF c.user %] <p><a href="/logout">Logout</a></p> <p>[% USE Dumper; Dumper.dump_html(c.user) %]</p> [% ELSE %] <p><a href="/login">Login</a></p> [% END %] </body> </html>
ログインセッションがあると、ユーザ情報がc.userに格納されるのでそれを使って分岐しています。ログインしていなければログインボタンを、ログインしていたらログアウトボタンとユーザ情報を表示しています。
lib/MyApp/Controller/Root.pm
sub index : Private {} sub login : Local { my ( $self, $c ) = @_; $c->res->redirect( $c->authenticate_hatena_url ); } sub logout : Local { my ( $self, $c ) = @_; $c->logout; $c->res->redirect( $c->uri_for('/') ); } sub auth_hatena : Local { my ( $self, $c ) = @_; if ( $c->authenticate_hatena ) { # login success } else { # login failed } $c->res->redirect( $c->uri_for('/') ); }
auth_hatenaは、はてな認証APIのコールバックです。ログインの基本的な流れは
- 認証APIに飛ばす。(sub login)
※ここでユーザが(必要であれば)パスワードを入力します。「パスワード入力が認証APIを提供しているサイトで行なわれる」というのが認証APIのミソです。はてな認証APIではアプリケーション側でフォームを用意する必要はありません。
- コールバック関数が呼ばれる。(sub auth_hatena)
- コールバック関数の中でログイン成功かどうかを判断する。
となります。
ログアウトはセッションを削除するだけです。
実行してみましょう
http://localhost:3000/にアクセスします。
Login
ログインボタンを押すとはてなにリダイレクトされ、初回のみ認証の許可を求められます。許可するとログインセッションができます。
Logout
$VAR1 = bless( {
'image_url' => '[]http://www.hatena.ne.jp/users/ho/holidays-l/profile.gif[]',
'name' => 'holidays-l',
'thumbnail_url' => '[]http://www.hatena.ne.jp/users/ho/holidays-l/profile_s.gif[]',
'__hash_obj_key_is_array' => {}
}, 'Catalyst::Plugin::Authentication::User::Hash' );
あっという間にできちゃいましたね!