Rails deviseの認証カスタマイズまとめ
ログイン機能に多く使われるgem devise のカスタマイズ方法をまとめる。
やりたいこと
- ユーザー名とパスワードで認証できるようにする
- アカウント登録・ログイン後の飛び先を変更する
ユーザー名とパスワードで認証できるようにする
devise のデフォルトではメールアドレスとパスワードで認証できるようになっているが、これをユーザー名とパスワードで認証できるようにしたい場合の設定方法。
1. モデルにカラムとインデックスを追加
既に devise 用の user モデルを作成している場合。今回はユーザー名として account_name というカラムを追加する。
$ rails g migration add_account_name_to_users account_name:string
マイグレートを実施する前に作成されたファイルを開き編集する。
追加したカラム(account_name)を認証に使うために、index と一意制約を追加する。
# db/migrate/20190307142742_add_username_to_users.rb class AddUsernameToUsers < ActiveRecord::Migration def change add_column :users, :account_name, :string add_index :users, :account_name, unique: true end end
マイグレートを実施し、モデルに反映。
$ rails db:migrate
Userモデルに追加したカラムの Validateを追加する。
class User < ActiveRecord::Base ... validates :account_rname, presence: true, uniqueness: true end
2. devise の認証キー設定を変更する
devise の設定ファイル( config/initializers/devise.rb )があるので、認証キーを email から password に変更する。ちなみに、このファイルでバリデーションの変更などいろいろカスタマイズできる。
# ==> Configuration for any authentication mechanism # Configure which keys are used when authenticating a user. The default is # just :email. You can configure it to use [:username, :subdomain], so for # authenticating a user, both parameters are required. Remember that those # parameters are used only when authenticating and not when retrieving from # session. If you need permissions, you should implement that in a before filter. # You can also supply a hash where the value is a boolean determining whether # or not authentication should be aborted when the value is not present. # config.authentication_keys = [:email] config.authentication_keys = [:account_name]
3. コントローラーにストロングパラメータの追加
deviseのストロングパラメータはデフォルトで email と password になっているので、ユーザー名も追加したストロングパラメータを呼べるようにメソッドを追加する。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base # deviceのコントローラーのときに、下記のメソッドを呼ぶ before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters added_attrs = [:account_name, :email, :password, :password_confirmation, :remember_me] devise_parameter_sanitizer.permit :sign_up, keys: added_attrs devise_parameter_sanitizer.permit :sign_in, keys: added_attrs devise_parameter_sanitizer.permit :account_update, keys: added_attrs end end
sign_up(アカウント登録), sign_in(ログイン), account_update(アカウント編集)のとき、 added_attrs の配列に格納されている要素を許可する。
4. View の入力フォームに作成したカラムの入力フィールド追加
アカウント登録画面、ログイン画面、プロフィール編集画面などの各 View に追加したカラムの入力フィールドを追加する。
下記はログイン時の画面。(form_for に設定されている url: login_path は私個人がカスタマイズした設定なので、カスタマイズしていない人は各々のデフォルトに従ってください。)
<h2>Log in</h2> <%= form_for(resource, as: resource_name, url: login_path) do |f| %> <div class="field"> <%= f.label :account_name %><br /> <%= f.text_field :account_name, autocomplete: "account_name" %> </div> <div class="field"> <%= f.label :password %><br /> <%= f.password_field :password, autocomplete: "current-password" %> </div> ...
最初は controller を独自にいじってやろうとしてしまいかなり苦戦したが、devise の設定を変更する必要があるだけで、生成された controller はあまりいじらない方がよかった。あと、ちゃんと公式にマニュアルが乗っているので、そのマニュアルを最初に参照してから他のブログ記事などを参照した方がよかった。
How To: Redirect to a specific page on successful sign in · heartcombo/devise Wiki · GitHub
リダイレクトの飛び先を変更する
デフォルトでは root にリダイレクトされる設定になっているので、変更したい場合は、after_sign_in_path_for(resource)メソッドを定義する必要がある。
# app/controllers/application_controller.rb def after_sign_in_path_for(resource) mypage_path end
devise の github の wiki ではフレンドリーフォワーディングの方法が紹介されているので、もし動的にログイン前のページに戻りたいという場合はこちらを参考にする。
How To: Redirect to a specific page on successful sign in · heartcombo/devise Wiki · GitHub
How To: Redirect to a specific page on successful sign in · heartcombo/devise Wiki · GitHub
devise のカスタマイズに関する記事はたくさん存在しているが、古い情報も多いので、鵜呑みにせずにま公式を見るようにしたい。