仕事で認証な必要なウェブアプリケーションを書いたことがあるのですが、Authlogicでできることと重複するようなことをやってることに気づきました。うーん、DRY。機会があれば、AuthlogicやDeviseなどを使って、書き直すことができればなぁ…
Authlogic
Authlogicは、簡潔で柔軟なRubyで記述された認証ソリューションです。コードで例示して説明した方がいいでしょう…
Authlogicでは新しい型のモデルを提供しています。他のモデルのようにいくつでもどんな名前で必要なだけ作成することができます。この例では、クラス名から分かるようにUserモデルを使って認証を行おうとしています。
class UserSession < Authlogic::Session::Base # ここでは以下のように設定項目を記述します: # logout_on_timeout true # ...その他の設定項目については文書を参照して下さい endログイン時には以下のいずれかの例を利用します。UserSessionControllerのインスタンスを作成して、他のモデルのように使用します。
UserSession.create(:login => "bjohnson", :password => "my password", :remember_me => true) session = UserSession.new(:login => "bjohnson", :password => "my password", :remember_me => true); session.save UserSession.create(:openid_identifier => "identifier", :remember_me => true) # authlogic-oidという「アドオン」gemパッケージが必要 UserSession.create(my_user_object, true) # 認証を回避してユーザーとして直接ログイン、第2引数のtrueは認証を記憶しておくという意味上記の例では認証処理の全てを処理します。最初に認証をして、それから、適切なセッションの値やセッションを維持するためのクッキーを設定します。自作の認証ソリューションを使うときと同じように処理を行います。 次のようにログアウト、もしくは、セッションを破棄することもできます:
session.destroyセッションが作成されてから、リクエスト間でそれを維持することができます。次のようにユーザーをログインした状態にします:
session = UserSession.find作成したモデルで便利な認証機能を利用したい場合は次のようにします:
class User < ActiveRecord::Base acts_as_authentic do |c| c.my_config_option = my_value end # 設定ブロックは任意 endこうして妥当性確認などを処理することができます。認証時にloginという列があればそれを使い、なければ、emailという列を使うというある意味「賢い」機能もあります。このような動作は全て設定可能ですが、ほとんどの場合において上記のような動作が必要となるだけでしょう。 また、セッションは自動的に管理されます。設定で管理を自動的に行うかどうかを切り替えることができますが、次の例では、登録が成功した後に自動的にユーザーをログインさせます:
User.create(params[:user])ユーザーがパスワードを変更した場合にもセッションを更新します。 Authlogicはとても柔軟で強力な公開APIがあり、動作の変更や拡張をするためのとても多くのフックがあります。詳細については以下のリンクを参照して下さい。
役立つリンク
- 文書: rdoc.info/projects/binarylogic/authlogic
- レポジトリ: github.com/binarylogic/authlogic/tree/master
- Railscastsスクリーンキャスト: railscasts.com/episodes/160-authlogic
- OpenID「アドオン」を使ったライブデモ: authlogicexample.binarylogic.com
- READMEにあるチュートリアルのライブデモ: github.com/binarylogic/authlogic_example/tree/master
- チュートリアル:
REST形式でのAuthlogicを使ったパスワードのリセット方法:
www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic
- 問題: github.com/binarylogic/authlogic/issues
- Googleグループ: groups.google.com/group/authlogic
Authlogicの「アドオン」
- Authlogic OpenIDアドオン: github.com/binarylogic/authlogic_openid
- Authlogic LDAPアドオン: github.com/binarylogic/authlogic_ldap
- Authlogic Facebook Connect: github.com/kalasjocke/authlogic_facebook_connect
- Authlogic OAuth (Twitter): github.com/jrallison/authlogic_oauth
- Authlogic PAM: github.com/nbudin/authlogic_pam
セッションのバグ(ログインやログアウトに問題がある場合には読んで下さい)
明らかにApache/Passenger バージョン2.1.Xには、セッションが正しく動作しないという不具合があります。ログインやログアウトの時に起こる問題がある場合には、大抵、この問題が原因です。これはAuthlogicの問題ではありません。Passengerをアップデートするかセッションの保存方法をActiveRecordでの保存などに変更することでこの問題を解決することができます。文書について
文書中にあるはずです。基本設計について理解するだけで十分です。 認証中に2つもモデルが関わっています。AuthlogicのモデルとActiveRecordのモデルです:- Authlogic::Session,
Authlogic::Session::Baseを拡張したセッションのモデル。
- Authlogic::ActsAsAuthentic,
acts_as_authenticを呼び出してActiveRecordモデルに追加された機能。
Authlogic::ActsAsAuthenticサブモジュール
これらのモジュールは、ActiveRecord用で、acts_as_authenticメソッドを呼んで利用することができます。- Authlogic::ActsAsAuthentic::Base - Provides the
acts_as_authenticというクラスメソッドを提供して、全てのサブモジュールを含んでいます。
- Authlogic::ActsAsAuthentic::Email -
emailの列に関しての全てを処理します。
- Authlogic::ActsAsAuthentic::LoggedInStatus -
便利な名前付きスコープとユーザーがログインしているかどうかを判定するメソッドを提供します。
- Authlogic::ActsAsAuthentic::Login -
loginの列に関しての全てを処理します。
- Authlogic::ActsAsAuthentic::MagicColumns -
login_count、failed_login_count、last_request_atなどの「特別な」列に関しての全てを処理します。
- Authlogic::ActsAsAuthentic::Password -
重要なモジュールで、パスワードを暗号化やsalt値を生成の生成を扱います。また、遷移パスワードアルゴリズムもサポートしています。
- Authlogic::ActsAsAuthentic::PerishableToken -
一時的なトークンの管理を扱います。また、トークンを使っているレコードを検索するためのクラスメソッドも提供します。
- Authlogic::ActsAsAuthentic::PersistenceToken -
永続的なトークンの管理を扱います。このトークンはユーザーのセッションを永続するためクッキーとセッション内に保存されます。
- Authlogic::ActsAsAuthentic::RestfulAuthentication -
restful_authenticationプラグインからの移行を簡単にするための設定オプションを提供します。
- Authlogic::ActsAsAuthentic::SessionMaintenance -
自動的なセッション管理を扱います。例えば、新規ユーザーの登録して自動的にログインさせたり、ユーザーがパスワードを変更して、セッションを更新するなどです。
- Authlogic::ActsAsAuthentic::SingleAccessToken -
ワンタイムアクセスのためのトークンの管理します。
- Authlogic::ActsAsAuthentic::ValidationsScope -
validates_uniqueness_ofの:scopeオプションのように全ての妥当性検査などにスコープを付けることができます。
Authlogic::Sessionサブモジュール
これらのモジュールはAuthlogic::Session::Baseを拡張したモデル用です。- Authlogic::Session::BruteForceProtection -
ある一定の回数続けてログインに失敗したアカウントを無効にします。
- Authlogic::Session::Callbacks -
Authlogicを拡張したり、変更したり、追加したりするためのツールです。大抵の事柄にフックして実行することができます。Authlogicのプラグインやアドオンを開発したい場合はここから始めて下さい。
- Authlogic::Session::Cookies - クッキーでの認証。
- Authlogic::Session::Existence -
オブジェクトの作成、保存、そして破棄。
- Authlogic::Session::HttpAuth - HTTPのBasic認証による認証。
- Authlogic::Session::Id -
IDによるセッションを有効にする。これによって、1人のユーザーが複数のセッションを使用できる。
- Authlogic::Session::MagicColumns -
ActiveRecordでのcreated_atやupdated_at列のようなデータベースでの「特別な」列を管理。
- Authlogic::Session::MagicStates -
active?、approved?、そして、confirmed?といったレコードの状態を元にした自動的な妥当性確認。これは対応するレコードが存在する場合のみ。
- Authlogic::Session::Params -
ワンタイムアクセストークンのようなパラメータでの認証。
- Authlogic::Session::Password -
伝統的なユーザー名とパスワードでの認証
- Authlogic::Session::Persistence -
セッションの永続化やセッションの検索
- Authlogic::Session::Session -
セッションでの認証。セッションコントローラそのものです。
- Authlogic::Session::Timeout -
ある一定時間活動がない場合、自動的にログアウト。
- Authlogic::Session::UnauthorizedRecord -
ActiveRecordのオブジェクトを直接渡すことでの認証の取り扱い。
- Authlogic::Session::Validation -
妥当性確認やエラー確認。
その他のモジュール
認証プロセスを通じて共有されるその他のモジュールや「ユーティリティ」モジュールやクラス。- Authlogic::AuthenticatesMany -
親のレコードへセッションにスコープを付けることができるようにする。has_manyやbelongs_toでの関係のようにセッションにも同じようなことができます。
- Authlogic::CryptoProviders -
Authlogicで利用する様々な暗号化アルゴリズムを含んでおり、どのアルゴリズムを使うかを選択することができます。
- Authlogic::I18n -
RailsのI18nライブラリと同じように動作して、Authlogicに国際化の機能を提供します。
- Authlogic::Random -
ランダムなトークンを生成するための単純なクラスです。
- Authlogic::Regex -
Authlogicでログや電子メールのフォーマットの妥当性を確認するための正規表現を含んでいます。
- Authlogic::TestCase -
作成したコードのテストを手助けするためのフレームワークをテストするための様々なヘルパーメソッド。
- Authlogic::Version -
数々の方法でAuthlogicのバージョンを確認するための便利なクラス。
Railsでの簡単な例
セッションの作成が表面上はORMライブラリのように動作するならどうなるでしょう…UserSession.create(params[:user_session])ユーザーセッションコントローラが他のコントローラのようであればどうなるでしょう…
class UserSessionsController < ApplicationController def new @user_session = UserSession.new end def create @user_session = UserSession.new(params[:user_session]) if @user_session.save redirect_to account_url else render :action => :new end end def destroy current_user_session.destroy redirect_to new_user_session_url end endごらんの通り、RESTfulの開発パターンに見事に当てはまります。ビューはどうなるでしょう…
<% form_for @user_session do |f| %> <%= f.error_messages %> <%= f.label :login %><br /> <%= f.text_field :login %><br /> <br /> <%= f.label :password %><br /> <%= f.password_field :password %><br /> <br /> <%= f.submit "Login" %> <% end %>また、セッションを永続化する場合には…
class ApplicationController helper_method :current_user_session, :current_user private def current_user_session return @current_user_session if defined?(@current_user_session) @current_user_session = UserSession.find end def current_user return @current_user if defined?(@current_user) @current_user = current_user_session && current_user_session.user end end
インストールと使い方
gem/プラグイン(推奨)でのインストール rubyforgeより:$ sudo gem install authlogicまたはgithubから:
$ sudo gem install binarylogic-authlogicそれから、プロジェクトの設定にgemの依存性を追加するだけです。 または、プラグインとしてインストールできます:
script/plugin install git://github.com/binarylogic/authlogic.git
詳細な設定チュートリアル
詳細な設定チュートリアルについては、Authlogicを使ったサンプルを参照して下さい。このサンプルを作ったのはチュートリアルのためだけではなく、同じチュートリアルで使うサンプルアプリケーションのコードを試すことができるからです。問題がある場合、何が違うのかを比較することもできます。テスト
Authlogicのもっとも良いことの一つはテストだと考えています。Authlogicは十分にテストが実施されているため、あなたのアプリケーションではたくさんの重複するテストを省略します。たくさんのテストはあなたのアプリケーションには含まれませんが、他のライブラリのようにAuthlogicはテストされた状態なのであなたのアプリケーションにはたくさんのテストが含まれません。 例えば、ActiveRecordについては、その内部のテストを実施しません。それは、ActiveRecordの作者たちが内部をテストしているからです。何百ものActiveRecordのテストをあなたのアプリケーションにコピーすることは意味をなしません。同じ事がAuthlogicにも言えるのです。他のアプリケーションのようにアプリケーション固有のコードをテストする必要があるだけです。 それはそれとして、Authlogic::TestCaseの項目をテストすることについてのあなたの疑問についての回答があるはずです。Authlogicの動作について簡単な説明
Authlogic全体がどのように動作するのか興味がありますか?ActiveRecordのモデルについて考えてみて下さい。私用できるようになるには、データベースへの接続が確立されている必要があります。Authlogicの場合は、コントローラへの接続が確立されている必要があります。クッキー、使用中のセッション、HTTPのBASIC認証によるログイン情報などを変更するためにコントローラへの接続を利用します。現在のコントローラオブジェクトについてをAuthlogicへ知らせるために自動的にコントローラに設定される前処理を行うフィルターを利用してコントローラへ接続します。Authlogicはフィルターを利用して全てのことを行います。とても簡単か設計です。なにも変なことをしていません。Authlogicは、コントローラオブジェクト内でフレームワークが提供するツールを利用しているだけです。Authlogicの特徴、及び、開発動機
Authlogicを作成する際に影響されたのはその時の認証ソリューションの乱雑さであった。つまり、ロジックが適切に整理されておらず、正しいとは思わなかった。知っているかもしれませんが、MVCデザインパターンでの一般的な誤解は、"M"で表されるモデルがデータアクセスのロジックのためだけだということです。それは間違いです。モデルは、問題ドメインのロジックのための場所なのです。この誤解がRESTfulデザインパターンと今までの認証ソリューションがうまく動作しなかった理由です。Authlogicでは、セッション管理ロジックをドメイン自身(または、モデル)内に配置することで、この問題を解決しています。セッション管理をドメイン自身に移動することの利点としては:- よりクリーンであること。Authlogicにはジェネレータがありません。Authlogicでは平易なRubyのクラスを提供しています。もっと重要なことにあなたのアプリケーション内のコードはあなたが書きたいように書いたコードで、素晴らしくてクリーンです。あなたのアプリケーションの一部であるべきコードであり、アプリケーション固有ですが、冗長な認証パターンではありません。
- 簡単に最新であり続けること。私の言いたいことを理解するために他の認証ソリューションへのコミットを見て下さい。それから、Authlogicのコミットで簡単に更新して最新のコードを使い始めることができます。
- ドメインレベルで全て結合していること。新規ユーザーの登録を例に取る場合、ユーザーをわざわざログインさせることは全く理由がありません。Authlogicはこれをコールバックで処理します。同じ事がユーザーがパスワードを変更するときにも言えます。Authlogicではあなたに代わってセッション管理を処理します。
- 重複するテストが無いこと。Authlogicはgeneratorを使わないので、テストにも1番目の利点が適用されます。Authlogicは、十分にテストされています。アプリケーションを開発する度にActiveRecordの内部を精査してテストをしませんよね?Authlogicに対しても同じ事をしますか?開発しているアプリケーションのテストはそれ固有のコードのためだけであるべきです。関係ない部分を取り除いて、テストコードを的を得た簡潔なものにしましょう。次々とアプリケーションに同じテストコードをコピーするのを止めましょう。
- フレームワークにとらわれないこと。Rackを見てみて下さい。
- 単一のセッションに縛られていないこと。Apple社のme.comについて考えてみて下さい。そこでは、支払い情報を変更する前にもう一度認証を行う必要があります。このために2つ目のセッションを作成するのはどうでしょうか?それははじめのセッションのように動作します。それから、支払い情報のコントローラが「超安全な」セッションを要求することができます。
- 簡単に拡張できること。ライブラリを利用する明らかな特徴の一つとして、APIがあるならそれを利用できることです。Authlogicには素晴らしい公開APIがあります。つまり、簡単に拡張できてコアライブラリでできないことを実現することができます。どういう意味かについては上記の「アドオン」一覧を見て下さい。
(終)
訳文に間違いや分かりにくい点があれば、コメントやメールで連絡を頂けると幸いです。
0 件のコメント:
コメントを投稿