【リニューアル記念】未経験からブロガーへのSTEPを続々更新!

Rails5にdeviseをサクッと導入!認証機能の使い方も解説【日本語化】

Railsにdeviseを導入する方法と使い方

Railsで何かしらのWebサイトを作るとなると、だいたい認証機能(ログイン機能)が必要になりますよね。

1から認証機能を作るとなると、実装やテストに多くの時間がとられるだけでなく、セキュリティの面から見ても不安が残ると思います。

そこでおすすめなのが「devise」というgemパッケージです。

deviseを使うことで、誰でも簡単に安全な仕組みで認証機能を実装することができます。

今回は、そんなdeviseをRails5に導入する手順を、1つずつ丁寧に紹介していきます。

deviseとは

deviseとは、Railsアプリケーションに認証機能を導入するためのgemパッケージです。

deviseを導入することで、以下のような機能が簡単に実装できるようになります。

  • サインイン、サインアウト機能
  • サインアップ機能(メール認証も可能)
  • アカウント登録、編集機能
  • パスワード変更、再発行機能

もちろん、各画面のデザインや制御のカスタマイズも可能です。

キツネ

認証機能がサクッと作れるのは驚きだよね!

Rails5にdeviseを導入する手順

ここでは、Rails5にdeviseを導入にする手順を、以下のステップで進めていきます。

  1. deviseのインストール
  2. deviseの初期設定
  3. deviseの認証モデル作成
  4. devise用のデータを作成
  5. ブラウザから確認

キツネ

手順は多いけど難しくないからね!

deviseのインストール

まずはdeviseをインストールしましょう。gemを使えば簡単にインストールできます。

以下をGemfileに追記し、bundle installを実行してdeviseをインストールしてみましょう。

Gemfile
gem 'devise'
deviseをインストール
$ bundle install

deviseの初期設定

deviseのインストールが終わったら、deviseの初期設定をしましょう。

初期設定は、rails g devise:installを実行することで、関連ファイルが自動で作成されます。

deviseの関連ファイルを作成
$ rails g devise:install
Running via Spring preloader in process 85
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

In production, :host should be set to 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>

4. You can copy Devise views (for customization) to your app by running:

rails g devise:views

===============================================================================

コマンドを実行すると、ファイル作成とともに上のような4つのステップが表示されます。

簡単にまとめると、以下のような内容になります。

  1. メールで使用するURLの設定
  2. ルーティングの設定
  3. 通知やアラートの表示用タグを追加
  4. Viewをカスタマイズする際のコマンド

1. メールで使用するURLの設定

deviseでは認証にメールを利用することができます。

その際、メールに記載されるデフォルトのURLをconfig/environments/development.rbに設定しておく必要があります。

いますぐ設定しなくても動くので、とりあえずスキップして、あとから設定するのでもいいですよ。

config/environments/development.rb
Rails.application.configure do
       :
       :
  # 認証メール内URL(例1)
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  # 認証メール内URL(例2)
  config.action_mailer.default_url_options = { protocol: 'https', host: '192.168.99.100' }
end

2. ルーティングの設定

root to: "home#index"のようなルートURLをconfig/routes.rbで設定しておいてね!って書いてあります。

すでに設定している場合は不要ですし、あとから自分の好きな画面に設定したい場合は、とりあえずスキップしても問題ありません。

3. 通知やアラートの表示タグを追加

ログインやアカウント登録時の「通知」や「エラー」を表示できるように、以下の2つのタグをapp/views/layouts/application.html.erbに追加する必要があります。

  • <p class="notice"><%= notice %></p>
  • <p class="alert"><%= alert %></p>
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>

キツネ

この設定をやらないと認証失敗時のエラーが表示されないよ!

4. Viewをカスタマイズする際のコマンド

deviseで利用する認証画面やアカウント登録画面などをカスタマイズをしたい場合は、rails g devise:viewsを実行するよう書いてあります。

Viewのカスタマイズは、後ほど詳しく解説するので、とりあえずスキップしても大丈夫です。

deviseの認証モデルを作成

deviseの初期設定が終わったので、rails g devise モデル名を実行して、「認証用モデル」と「マイグレーションファイル」を作成します。

これにより、指定したモデルでdeviseの認証機能が使えるようになります。ここでは「user」を指定しています。

devise用のユーザーモデルを作成
$ rails g devise user
Running via Spring preloader in process 102
      invoke  active_record
      create    db/migrate/20190704023955_devise_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      insert    app/models/user.rb
       route  devise_for :users

また、config/routes.rbにdevise用のルーティングが自動で設定されているので確認します。

config/routes.rb
Rails.application.routes.draw do
  devise_for :users
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

rails routesを実行して、deviseのルーティングがどのように設定されたのかも確認しておきましょう。

ルーティングを確認
$ rails routes
                   Prefix Verb   URI Pattern                      Controller#Action
         new_user_session GET    /users/sign_in(.:format)         devise/sessions#new
             user_session POST   /users/sign_in(.:format)         devise/sessions#create
     destroy_user_session DELETE /users/sign_out(.:format)        devise/sessions#destroy
        new_user_password GET    /users/password/new(.:format)    devise/passwords#new
       edit_user_password GET    /users/password/edit(.:format)   devise/passwords#edit
            user_password PATCH  /users/password(.:format)        devise/passwords#update
                          PUT    /users/password(.:format)        devise/passwords#update
                          POST   /users/password(.:format)        devise/passwords#create
 cancel_user_registration GET    /users/cancel(.:format)          devise/registrations#cancel
    new_user_registration GET    /users/sign_up(.:format)         devise/registrations#new
   edit_user_registration GET    /users/edit(.:format)            devise/registrations#edit
        user_registration PATCH  /users(.:format)                 devise/registrations#update
                          PUT    /users(.:format)                 devise/registrations#update
                          DELETE /users(.:format)                 devise/registrations#destroy
                          POST   /users(.:format)                 devise/registrations#create

「/users/sign_in」がログイン画面、「/users/sign_up」はアカウント登録画面でルーティングされていることがわかると思います。

devise用のデータを作成

最後に、deviseによって自動作成されたマイグレーションファイルをDBに適用して完了です。

DBのデータを作成
$ rails db:migrate
== 20190704031339 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.1317s
-- add_index(:users, :email, {:unique=>true})
   -> 0.1135s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.1127s
== 20190704031339 DeviseCreateUsers: migrated (0.3600s) =======================

キツネ

これでdeviseが使えるようになったよ!

ブラウザから確認

deviseログイン画面

これでdeviseを使った認証機能が利用できるはずです。

「http://IPアドレス/users/sign_in」にブラウザからアクセスして、上のような画面が表示されるか確認してみましょう。

deviseログイン画面エラー

deviseログイン画面エラー2

もし、上のような「NoMethodError」や「Routing Error」が出ている場合は、Rails(Puma)を再起動させてからアクセスしてみてください。

deviseのメッセージを日本語化

このままdeviseを使ってもいいのですが、「デフォルトの表示を日本語化したい」という方もいるでしょう。

実は、deviseの日本語化パッケージを使えば、スマートに日本語化できます。

日本語化パッケージのインストール

まずは、Gemfileに以下を追記してgemパッケージをインストールしましょう。

Gemfile
gem 'devise-i18n'
gem 'devise-i18n-views'
日本語化パッケージをインストール
$ bundle install

日本語ファイルを使用するように設定

次に、config/application.rbを開いて、config.i18n.default_locale = :jaを追加し、deviseの日本語化ファイルを読み込むように設定します。

config/application.rb
$ require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module App
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    config.i18n.default_locale = :ja <(追加)

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

日本語ファイルを生成

最後に、rails g devise:views:locale jaを実行して、deviseの日本語化ファイルを生成します。

deviseの日本語化
$ rails g devise:views:locale ja
Running via Spring preloader in process 43
create config/locales/devise.views.ja.yml

これでdeviseの日本化は完了です。

ちなみに、自動生成された以下のconfig/locales/devise.views.ja.ymlを変更することで、表示される日本語メッセージのカスタマイズも可能です。

config/locales/devise.views.ja.yml
ja:
  activerecord:
    attributes:
      user:
        current_password: "現在のパスワード"
        email: "メールアドレス"
        password: "パスワード"
        password_confirmation: "確認用パスワード"
        remember_me: "ログインを記憶"
    models:
      user: "ユーザ"
  devise:
    confirmations:
      new:
        resend_confirmation_instructions: "アカウント確認メール再送"
    mailer:
      confirmation_instructions:
        action: "アカウント確認"
        greeting: "ようこそ、%{recipient}さん!"
        instruction: "次のリンクでメールアドレスの確認が完了します:"
      reset_password_instructions:
        action: "パスワード変更"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "誰かがパスワードの再設定を希望しました。次のリンクでパスワードの再設定が出来ます。"
        instruction_2: "あなたが希望したのではないのなら、このメールは無視してください。"
        instruction_3: "上のリンクにアクセスして新しいパスワードを設定するまで、パスワードは変更されません。"
      unlock_instructions:
        action: "アカウントのロック解除"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "アカウントのロックを解除するには下のリンクをクリックしてください。"
        message: "ログイン失敗が繰り返されたため、アカウントはロックされています。"
    passwords:
      edit:
        change_my_password: "パスワードを変更する"
        change_your_password: "パスワードを変更"
        confirm_new_password: "確認用新しいパスワード"
        new_password: "新しいパスワード"
      new:
        forgot_your_password: "パスワードを忘れましたか?"
        send_me_reset_password_instructions: "パスワードの再設定方法を送信する"
    registrations:
      edit:
        are_you_sure: "本当に良いですか?"
        cancel_my_account: "アカウント削除"
        currently_waiting_confirmation_for_email: "%{email} の確認待ち"
        leave_blank_if_you_don_t_want_to_change_it: "空欄のままなら変更しません"
        title: "%{resource}編集"
        unhappy: "気に入りません"
        update: "更新"
        we_need_your_current_password_to_confirm_your_changes: "変更を反映するには現在のパスワードを入力してください"
      new:
        sign_up: "アカウント登録"
    sessions:
      new:
        sign_in: "ログイン"
    shared:
      links:
        back: "戻る"
        didn_t_receive_confirmation_instructions: "アカウント確認のメールを受け取っていませんか?"
        didn_t_receive_unlock_instructions: "アカウントの凍結解除方法のメールを受け取っていませんか?"
        forgot_your_password: "パスワードを忘れましたか?"
        sign_in: "ログイン"
        sign_in_with_provider: "%{provider}でログイン"
        sign_up: "アカウント登録"
    unlocks:
      new:
        resend_unlock_instructions: "アカウントの凍結解除方法を再送する"

Viewをカスタマイズする場合

deviseでは、デフォルトの認証画面やアカウント登録画面をそのまま利用できるようになっています。

ですが、「自分でViewをカスタマイズしたい!」という場合もあると思います。

そんなときは、config/initializers/devise.rbに以下のコードを追記し、カスタマイズを有効にします。

config/initializers/devise.rb
config.scoped_views = true

あとは、rails g devise:views usersを実行し、カスタマイズ用のViewテンプレートを作成しましょう。

この自動生成されたファイルを好きなように編集することで、各画面のカスタマイズが可能になります。

devise用のViewを作成
$ rails g devise:views users
Running via Spring preloader in process 41
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/users/shared
      create    app/views/users/shared/_error_messages.html.erb
      create    app/views/users/shared/_links.html.erb
      invoke  form_for
      create    app/views/users/confirmations
      create    app/views/users/confirmations/new.html.erb
      create    app/views/users/passwords
      create    app/views/users/passwords/edit.html.erb
      create    app/views/users/passwords/new.html.erb
      create    app/views/users/registrations
      create    app/views/users/registrations/edit.html.erb
      create    app/views/users/registrations/new.html.erb
      create    app/views/users/sessions
      create    app/views/users/sessions/new.html.erb
      create    app/views/users/unlocks
      create    app/views/users/unlocks/new.html.erb
      invoke  erb
      create    app/views/users/mailer
      create    app/views/users/mailer/confirmation_instructions.html.erb
      create    app/views/users/mailer/email_changed.html.erb
      create    app/views/users/mailer/password_change.html.erb
      create    app/views/users/mailer/reset_password_instructions.html.erb
      create    app/views/users/mailer/unlock_instructions.html.erb

Controllerをカスタマイズする場合

Viewだけでなく、Controllerを変更してdeviseのデフォルトの動きを変更したい場合もあると思います。

これも同じようにrails g devise:controllers usersを実行して、生成されたファイルを編集することでカスタマイズできます。

devise用のControllerを作成
$ rails g devise:controllers users
Running via Spring preloader in process 48
      create  app/controllers/users/confirmations_controller.rb
      create  app/controllers/users/passwords_controller.rb
      create  app/controllers/users/registrations_controller.rb
      create  app/controllers/users/sessions_controller.rb
      create  app/controllers/users/unlocks_controller.rb
      create  app/controllers/users/omniauth_callbacks_controller.rb
===============================================================================

Some setup you must do manually if you haven't yet:

  Ensure you have overridden routes for generated controllers in your routes.rb.
  For example:

    Rails.application.routes.draw do
      devise_for :users, controllers: {
        sessions: 'users/sessions'
      }
    end

===============================================================================

deviseの使い方

deviseでは、頻繁に使うであろう関数があらかじめ用意されています。

これらの関数を使って、ログイン制御やユーザー情報の取得をおこないます。

deviseの使い方
# ログインユーザーのみアクセス許可(Controllerに記述)
before_action :authenticate_user!

# indexアクションはログインユーザーのみアクセス許可(Controllerに記述)
before_action :authenticate_user!, only: [:index]

# ユーザーがログイン済みかチェック
user_signed_in?

# ログインユーザーの情報を取得
current_user

# ユーザーのセッション情報を取得
user_session

キツネ

自分で実装しなくていいから、とっても楽だね!

まとめ

deviseを利用することで、Railsにサクッと認証機能を導入することができます。

認証機能の仕組みを知ることも大切ですが、時間を節約し効率よく開発することも大切です。

deviseには拡張性があり、カスタマイズするとさらに多くの時間が必要になってきますからね。

カスタマイズに関しては、勉強がてら自分で調べながら実装してみてください!

テキストのコピーはできません。