Rails3アプリにDeviseで簡単に認証システムを組み込む
co-meetingではユーザ管理をDeviseをベースに開発しています。
開発過程でDeviseについて調べたことを、何度かに分けて書いていこうと思います。
Devise(http://rubygems.org/gems/devise)とは、Railsアプリにログインの仕組みを組み込む場合にデファクトスタンダードになっているgemで、メールによるコンファームなど必要な仕組みが揃っていて非常に便利です。*1
Rails3のインストールからプロジェクトの作成、Deviseの使い方については以下のサイトで詳しく解説されています。
http://www.oiax.jp/rails/rails3.html
チュートリアル的に習得するならこちらのページの方が参考になります。
ここでは、Deviseの導入から、独自ログインのみのシステムでDeviseを使うに当たって最低限必要と思われる設定についてのみまとめていきます。
scaffoldでアプリを生成
Deviseを試すためのアプリをscaffoldで作成しておきます。
scaffoldを使ったアプリ作成については以下を参考にしました。
Rails3のscaffoldを試す
Deviseのインストール
gemのインストール
Gemfileに以下を追加して、bundle installします。
gem 'devise', '1.4.2'
$ bundle install
Railsプロジェクトにインストール
$ rails g devise:install hrendoh@hrendoh-UL20A:~/workspace-rails/hello-device$ 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: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> ===============================================================================
1. config/environments/development.rbの最後に「config.action_mailer.default_url_options = { :host => 'localhost:3000' }」を追記
...
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
end
2. config/routes.rbに「root :to => "item#index"」を追記
...
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
root :to => "items#index"
end
Deviseはログイン、アカウントのコンファームおよびパスワードの変更の後、root :toに指定されたパスにアクセスします。*2
(public/index.htmlを消すのを忘れずに)
3. とりあえずapp/views/layouts/application.html.erbのbodyの一番上に追記
<!DOCTYPE html> <html> <head> <title>HelloDevice</title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </head> <body> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html>
Controllerに認証チェックを追加
app/controller/items_controller.rbに認証チェックのフィルターを追加
before_filter :authenticate_user!
メール送信設定
config/environments/development.rbの以下の「config.action_mailer.raise_delivery_errors = false」をコメントにする
# Don't care if the mailer can't send
#config.action_mailer.raise_delivery_errors = false
producation.rbはデフォルトでコメントされています。
SMTPサーバーの設定
config/environments/development.rbに以下を追記
config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => 'smtp.gmail.com', :port => 587, :authentication => :plain, :user_name => 'hrendoh@gmail.com', :password => '****' }
サインアップ時に確認メールを出す
サインアップ時に確認メールを送信するかどうかの設定はdeviseのモデル app/models/user.rbのdeviseメソッドの引数として指定します。
confirmableを追加します。
devise :database_authenticatable, :registerable,:confirmable,
:recoverable, :rememberable, :trackable, :validatable
db/migrate/nnnnnn_devise_create_users.rbのt.confirmableのコメントを外します。
create_table(:users) do |t|
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
# t.encryptable
t.confirmable
# t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
# t.token_authenticatable
t.timestamps
確認メールの「Confirm my accounts」のリンクを変更するには、config/environments/development.rbに設定する場合、以下の箇所を修正します。
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
ビューのカスタマイズ
最後にビューのカスタマイズについて説明します。
Deviseのビューをプロジェクトにコピーします。
$ rails generate devise:views devise:views invoke Devise::Generators::SharedViewsGenerator create app/views/devise/mailer create app/views/devise/mailer/confirmation_instructions.html.erb create app/views/devise/mailer/reset_password_instructions.html.erb create app/views/devise/mailer/unlock_instructions.html.erb create app/views/devise/shared create app/views/devise/shared/_links.erb invoke form_for create app/views/devise/confirmations create app/views/devise/confirmations/new.html.erb create app/views/devise/passwords create app/views/devise/passwords/edit.html.erb create app/views/devise/passwords/new.html.erb create app/views/devise/registrations create app/views/devise/registrations/edit.html.erb create app/views/devise/registrations/new.html.erb create app/views/devise/sessions create app/views/devise/sessions/new.html.erb create app/views/devise/unlocks create app/views/devise/unlocks/new.html.erb
生成されたそれぞれのビューを編集すると、デフォルトのビューの変わりに表示されるようになります。
例えば、ログインフォームを編集する場合は、以下のファイルを編集します。
app/views/devise/sessions/new.html.erb
*1:実際には、デフォルトの機能に独自の仕組みを追加しようとすると大抵はgemのソースを読む羽目になりそうな感じなので、システム構成が大きくなりそうなアプリケーションの場合は設計の参考にするくらいが良いかもしれません。
*2:Rails3のルーティングについてはこちら:http://guides.rubyonrails.org/routing.html