Home > howto > Catalyst でかんたんログインを実装する

Catalyst でかんたんログインを実装する

前回の、Catalyst でオートログインとブラウザを閉じるまで有効な Cookie を共存の続きです。

mixi などで実装されている、携帯端末固有情報や契約者識別情報を利用した、「かんたんログイン」を実装する方法を紹介します。

まずは、ユーザー情報のテーブルに uid を格納するカラムを用意します。Schema も変更するのを忘れずに。

ユーザーがログインした後のページで、かんたんログインの設定をするページを作ります。


package MyApp::Controller::User;

sub uid_update : Path('uid/update') {
    my ( $self, $c ) = @_;
    $c->user->mobile_uid($c->req->mobile_agent->user_id());
    $c->user->mobile_agent($c->req->user_agent());
    $c->user->update();
}

sub uid_delete : Path('uid/delete') {
    my ( $self, $c ) = @_;
    $c->user->mobile_uid(undef);
    $c->user->mobile_agent(undef);
    $c->user->update();
}

$c->authenticate() に渡す認証情報の振り分けを追加します。


sub auth_info {
    my ( $self, $c ) = @_;
    my (%userinfo, $realms);
    # かんたんログイン
    if ($c->req->param('easylogin') && !$c->req->mobile_agent->is_non_mobile) {
        %userinfo = (
            'mobile_uid'   => $c->req->mobile_agent->user_id(),
            'mobile_agent' => $c->req->user_agent()
        );
        $realms = 'users_mobile';
    }
    # パスワードログイン
    else {
        $c->form(
            user => [ qw/NOT_BLANK/ ],
            pass => [ qw/NOT_BLANK ASCII/, [qw/LENGTH 4 32/] ],
        );
        %userinfo = (
            user => $c->req->param('user'),
            pass => $c->req->param('pass'),
        );
        $realms = 'users';
    }
    return (\%userinfo, $realms);
}

実際の認証するところはこんな感じです。


    my @auth_info = $self->auth_info($c);
    return if $c->form->has_error();

    if (!$c->authenticate(@auth_info)) {
        $c->set_invalid_form('login' => 'LOGIN');
        return;
    }

Catalyst::Authentication::Credential::Password は、デフォルトだと当たり前ですがパスワード認証しようとするので、password_field で指定したデータを渡さないと check_password() に怒られます。

password_type
    This sets the password type.  Often passwords are stored in crypted or hashed formats.
    In order for the password module to verify the plaintext password passed in, it must
    be told what format the password will be in when it is retreived from the user object.
    The supported options are:

    none    No password check is done. An attempt is made to retrieve the user based on
            the information provided in the $c->authenticate() call. If a user is found,
            authentication is considered to be successful.

ですので、以下のように password_type を none にして回避します。


authentication:
    default_realm: 'users'
    realms:
        users:
            credential:
                class: 'Password'
                password_field: 'passwd'
                password_type: 'hashed'
                password_hash_type: 'MD5'
            store:
                class: 'DBIx::Class'
                user_class: 'DBIC::User'
                id_field: 'user'
        users_mobile:
            credential:
                class: 'Password'
                password_type: 'none'
            store:
                class: 'DBIx::Class'
                user_class: 'DBIC::User'
                id_field: 'user'

howto ,

  1. コメントはまだありません。
  1. No trackbacks yet.