Devise
Railにユーザ認証機能を追加するプラグイン。 ユーザに相当する既存モデルに認証機能を追加することも可能。
目次 |
インストールと初期設定
まずGemfileに次を追加
gem 'devise'
次にbundle installを実行。 依存パッケージのorm_adapter、wardenもインストールされる
> bundle install
最後にrails g devise:install を実行
> rails g devise:install
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
1. Setup default url options for your specific environment. Here is an
example of development environment:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
This is a required Rails configuration. In production it must be the
actual host of your application
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root :to => "home#index"
&
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<%= notice %>
<%= alert %>
4. If you are deploying Rails 3.1 on Heroku, you may want to set:
config.assets.initialize_on_precompile = false
On config/application.rb forcing your application to not access the DB
or load models when precompiling your assets.
===============================================================================
インストール後は上記の実行時のメッセージに従い、設定を追加する。
config/environments/development.rb に次を追加する。(実運用環境に移すときにはconfig/environments/production.rbに追加)
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config/routes.rb に rootのルーティングを追加。指定するアクションはアプリケーションに応じて設定する。
root :to => "welcome#index"
app/views/layouts/application.html.erbに次を追加。
<p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p>
アプリケーションへの適用
アプリケーションのユーザを表すモデルに認証機能を追加することができる。
モデルクラスには認証機能に必要なコードが挿入されるが、migrateファイルは新たに作られるので、fixture等は使えなくなる。 なにより属性の一部が暗号化されたりするのでfixtureという仕組みでデータを作れなくなるので注意。
以下、既存のMemberクラスを認証クラスとする場合の例で説明する(あえて、よく使われるUserは使わない)
Memberモデルに認証機能を追加
rails g devise Member
この結果、次の様なコードが挿入される。
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
また、config/routes.rbに devise_for を追加するようにREADMEには書いてあるが、上記のコマンドで自動的に追加されている。
今回の例の場合次の様なコードが挿入されている。
devise_for :members
ユーザ登録時の処理のカスタマイズ
ユーザの登録処理は Devise::RegistrationsController#create で実行されているのでこれをオーバーライドすればカスタマイズ可能と思われる。 例えばUser::RegistrationsController を作る場合、次の様にクラスを定義する。
class User::RegistrationsController < Devise::RegistrationsController end
そして、このクラスに処理させるにはルーティングに次のように書き換える。赤字の部分で処理するコントローラを指定する。
devise_for :customers, :controllers =>{ :registrations =>"user/registrations"}
ログイン、ログアウト後の遷移先のカスタマイズ
ログインするとroot:toで指定したURLに遷移するが、ひとつのアプリで複数のモデルに別々の認証を用意する場合(一般ユーザ用と管理者用など)、ログイン、ログアウト後の遷移先を別々にしたい場合がある。
その場合、まず、Devise::SessionsControllerを継承したコントローラクラスを作り、次のメソッドを実装する
- after_sign_in_path_for
- after_sign_out_path_for
実装例は次の通り。
class Admins::RegistrationsController < Devise::RegistrationsController
layout 'admins/layouts/application.html.erb'
private
# Overwriting the sign_out redirect path method
def after_sign_out_path_for(resource_or_scope)
new_admin_session_path
end
def after_sign_in_path_for(resource)
stored_location_for(resource) || admins_root_path
end
end
でこのクラスを標準のセッションコントローラーの代わりに使うようにroute.rbに設定する
devise_for :admins, :controllers =>{ :sessions=>"admins/sessions"}
ログイン認証に独自条件を追加する
ログイン時に、メアド、パスワードの正当性だけでなく、ログインを許可するか否かに別の条件も追加したいことがある。 例えば、ユーザのステータスや有効期限によってログイン可否を判定したいなど。
その場合には認証モデルの active_for_authentication? メソッドをオーバーライドする。 例えば、account_active?というメソッドで独自ログイン可否判定ロジックを実装した場合には次の様になる。
def active_for_authentication? super && account_active? end