こたつとみかんとプログラミング

33才実務未経験ですがウェブエンジニアにジョブチェンジするために勉強したことをアップするためのブログです。

Rails deviseの認証カスタマイズまとめ

ログイン機能に多く使われるgem devise のカスタマイズ方法をまとめる。

やりたいこと

  1. ユーザー名とパスワードで認証できるようにする
  2. アカウント登録・ログイン後の飛び先を変更する

環境

ユーザー名とパスワードで認証できるようにする

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 の githubwiki ではフレンドリーフォワーディングの方法が紹介されているので、もし動的にログイン前のページに戻りたいという場合はこちらを参考にする。
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 のカスタマイズに関する記事はたくさん存在しているが、古い情報も多いので、鵜呑みにせずにま公式を見るようにしたい。