この記事について
deviseはRailsでユーザー認証を扱うときに非常に便利なgemです
初めて自分でDevise使ってユーザー認証周りを作ったので、その際に調べたこと・試したことなどを備忘録的に残しておきます
今回の使用したdeviseのバージョンはv4.2.0
です
gemのインストール
Gemfileに以下を追記してbundle install
を実行
gem 'devise'
設定ファイルなどの生成
rails g devise:install
で設定ファイルやViewで用いられるlocaleファイルが生成されます
以下は生成されたファイル
- config/initializers/devise.rb (設定ファイル)
- パッと見変更しそうなものは2つぐらい
- config.mailer_sender(送信元のアドレス)
- config.password_length(パスワードの長さ, デフォルトは6文字以上128文字以下)
- config/locales/devise.en.yml (localeファイル)
- 日本語のlocaleファイルの追加方法は後ほど詳述
- config/environments/development.rb (登録周りで飛ぶメールのホスト指定が追記される)
-
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
が追記される
-
ユーザーモデルの生成
rails g devise Model
でモデルやマイグレーションが生成されます
Modelの部分にはUserやAdminなどが入るものと思ってください
以下はrails g devise User
で生成されたファイル
- app/models/user.rb
- config/routes.rb
- db/migrate/20170211042541_devise_create_users.rb
- test/fixtures/users.yml
- test/models/user_test.rb
generateコマンドで生成された段階ではモデルは以下のようになっています
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
見て分かる通りデフォルトでは以下の機能が有効となっています
module | 機能 |
---|---|
database_authenticatable | DBに保存するパスワードの暗号化(必須) |
registerable | サインアップ処理 |
recoverable | パスワードリセット |
rememberable | クッキーにログイン情報を保持 |
trackable | サインイン回数・時刻・IPアドレスを保存 |
validatable | メールアドレスとパスワードのバリデーション |
また、コメントにある通り以下の機能を利用したい場合はモジュール名の追記が必要となります
その場合、マイグレーションにも対応するコメントアウトがあるのでそちらもコメントインしましょう
特にconfirmableあたりはよく使うことになると思うので注意が必要です
module | 機能 |
---|---|
confirmable | メール送信による登録確認 |
lockable | 一定回数ログインに失敗した際のアカウントロック |
timeoutable | 一定時間でセッションを削除する |
omniauthable | OmniAuthサポート |
モジュール追加の編集が終わったらrake db:migrate
し、/users/sign_up
にアクセスすればデフォルトの登録画面が表示されます
View/Controllerのカスタマイズ
Viewの生成
ここまでで認証自体は可能になりましたが、実際の開発で利用するにあたってはViewのカスタマイズが必要になると思います
rails g devise:views Model
でModelに対応するViewが生成されます
以下は生成されたファイルです
これらのファイルをカスタマイズすればOKです
- app/views/users/confirmations/new.html.erb
- app/views/users/mailer/confirmation_instructions.html.erb
- app/views/users/mailer/password_change.html.erb
- app/views/users/mailer/reset_password_instructions.html.erb
- app/views/users/mailer/unlock_instructions.html.erb
- app/views/users/passwords/edit.html.erb
- app/views/users/passwords/new.html.erb
- app/views/users/registrations/edit.html.erb
- app/views/users/registrations/new.html.erb
- app/views/users/sessions/new.html.erb
- app/views/users/shared/_links.html.erb
- app/views/users/unlocks/new.html.erb
Controllerの生成
コントローラーで行う処理を変更したい場合はrails g devise:controllers Model
でControllerを生成することができます
以下は生成されたファイルです
- app/controllers/users/confirmations_controller.rb
- app/controllers/users/omniauth_callbacks_controller.rb
- app/controllers/users/passwords_controller.rb
- app/controllers/users/registrations_controller.rb
- app/controllers/users/sessions_controller.rb
- app/controllers/users/unlocks_controller.rb
この場合、生成されたControllerはDevise::RegistrationController
などのコントローラーを継承する形になっており、デフォルトではすべてのメソッドが親クラスのメソッドを呼び出した状態でコメントアウトされています
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# GET /resource/sign_up
# def new
# super
# end
# ...
さらに、ルーティングを変更する必要があります
この例ではunlockとomniauthは利用してないのでルーティング変更してません
devise_for :users, controllers: {
confirmations: 'users/confirmations',
passwords: 'users/passwords',
registrations: 'users/registrations',
sessions: 'users/sessions',
}
これで、特定の条件下でのみconfirmationをスキップする、confirmation時に追加のユーザー情報を登録させるなどの細かな挙動のカスタマイズが可能になると思います(まだ試してないけど)
(参考)
deviseでconfirmable設定をした際の確認メールをスキップさせる skip_confirmation! は、対象のオブジェクトをsaveする前に書く - Qiita
deviseのStrongParameterまわり
TODO: 余裕があれば後で書く
deviseのi18n対応
今回作ったサイトでは日本語と英語に対応してほしいとの要望があったので、deviseのi18n対応についても簡単に調べてみました
deviseのWikiに各言語のロケールファイルの一覧が載っているのでこの中からおめあてのものを探しましょう
I18n · plataformatec/devise Wiki
DLしたらconfig/locale/devise.Lang.yml
にロケールファイルを置いてあげましょう
日本語の場合ならconfig/locale/devise.ja.yml
です
すでにデフォルトのロケールが日本語になっていれば問題ないですが、そうでなければconfig/application.rb
の中でデフォルトのロケールを変更してあげましょう
module WPCS2
class Application < Rails::Application
# ...
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :ja
# ...
end
end
これでエラーメッセージなどが日本語化されます
(一部、追加しないとtranslationに失敗する部分もあるようですが)
=== 2017/02/20追記 ===
ビューについてはdevise-i18n
というgemがあるのでそちらを使いましょう
tigrish/devise-i18n: Translations for the devise gem
まずはGemfileに gem devise-i18n
を追記してインストール
そして、viewを rails g devise:i18n:views
で生成できます
生成されたビューはapp/views/devise
に置かれるので app/views/users
などにリネームしましょう
これだけだとビューに書かれたパーシャルの描画指定などが矛盾してしまうので、 render "devise/..."
と成っている部分のdeviseをusersに書き換えます
最後に rails g devise:i18n:locale ja
などとしてロケールファイルを生成します
ロケールファイルの中を開いて、deviseとなっているところをusersに変えましょう
また、これだけだと一部のエラーメッセージなどがtranslation missingになってしまう場合があります
rails-i18nというリポジトリに汎用的に使えるロケールファイルのテンプレートがあるのでダウンロードして config/locale/ja.yml
に配置しましょう
(まぁ、これはdeviseに限らずi18n対応するなら一番最初にやっておくべきことなのですが)
svenfuchs/rails-i18n: Repository for collecting Locale data for Ruby on Rails I18n as well as other interesting, Rails related I18n stuff
=== 追記終わり ===
まとめ
deviseを使うことで非常に簡単にユーザー認証機能を作成できます
今回は試してないですが、OmniAuthまわりもサポートがあるようなので、TwitterやFacebookなどのアカウントでログインといった機能も簡単に実装できるようです(あんまりよくわかってないけど)
できれば、中でどんな処理を行っているのかも簡単に把握しておくといざというときも対処ができてよいかもしれません