deviseのインストール手順をシンプルなログイン機能の実装で理解する

Ruby

deviseを利用することで簡単に認証機能をRailsアプリケーションに構築できます。
今回はdeviseをインストールする手順について紹介します。

今回のゴール
  • deviseのセットアップ手順について理解する
  • メールアドレス・パスワードを利用した認証の実装方法について理解する
  • 認証情報を保存しているセッションの実態について理解する

今回実装する内容について

deviseを利用するとさまざまなことができますが、今回の記事はdeviseのインストール手順が焦点のため、認証はシンプルな実装にします。

今回実装するアプリケーションについて
  • メールアドレスとパスワードを利用してサインアップ・サインインできるアプリケーションを作成
  • サインアップ・サインイン・サインアウト後はルート(/)へ遷移させる
  • メール認証、ログイン状態の記憶、パスワードの変更などは実装しない

gemのインストール

devise gemをインストールします。

Gemfile

gem 'devise'

Gemfile編集後、bundle installを実行します。

$ bundle install

deviseのセットアップ

deviseの初期設定をするジェネレータ(devise:install)を実行します。

$ rails generate devise:install

Running via Spring preloader in process 270
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Depending on your application's configuration some manual setup may be required:

  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.

     * Required for all applications. *

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

     * Not required for API-only Applications *

  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>

     * Not required for API-only Applications *

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

       rails g devise:views

     * Not required *

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

devise:installを実行すると、deviseの設定ファイル(config/initializers/devise.rbconfig/locales/devise.en.yml)の生成と、セットアップ手順の表示がされます。

コンソールの出力からもわかるように、deviseのセットアップ手順は以下の通りです。

deviseのセットアップ手順
  1. デフォルトURLの設定
  2. ルートURLの作成
  3. フラッシュメッセージの作成
  4. deviseに関するビューの作成

以下ではそれぞれの項目について説明します。

デフォルトURLの設定

各環境(developmentやproduction)で利用するデフォルトのURLを設定します。

たとえば、Action Mailerを利用して認証やパスワードリセットのメールを送信する場合、以下のような設定を追加します。

config/environments/development.rb

config.action_mailer.default_url_options = { host: Settings.host_name }

config/settings/development.yml

host_name: localhost:3000
今回の場合はデフォルトURLの設定は不要です。

ルートURLの作成

deviseでは、サインアップ・サインイン・サインアウト後はデフォルトでルート(/)へ遷移します。
deviseのデフォルトの設定を利用する場合、ルート画面を作成する必要があります。
今回は例としてhome#indexをルートURLに設定します。

ルーティングを追加します。

config/routes.rb

root to: 'home#index'

コントローラとビューを作成します。

$ rails g controller Home index

フラッシュメッセージの作成

サインアップやサインアウトの結果をフラッシュメッセージとして表示したい場合はレイアウトを編集します。
今回フラッシュメッセージの実装は行わないので説明を省略します。

deviseに関するビューの作成

deviseに関するビューを作成します。
devise:viewsでサインアップやサインインなど、認証に必要な画面が一括で作成できます。

$ rails g devise:views

invoke  Devise::Generators::SharedViewsGenerator
create    app/views/devise/shared
create    app/views/devise/shared/_error_messages.html.erb
create    app/views/devise/shared/_links.html.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 (ロック解除メール再送信画面)
invoke  erb
create    app/views/devise/mailer
create    app/views/devise/mailer/confirmation_instructions.html.erb (メール用アカウント認証文)
create    app/views/devise/mailer/email_changed.html.erb
create    app/views/devise/mailer/password_change.html.erb (メール用パスワード変更完了文)
create    app/views/devise/mailer/reset_password_instructions.html.erb(メール用パスワードリセット文)
create    app/views/devise/mailer/unlock_instructions.html.erb (メール用ロック解除文)

モデルの作成

認証機能を利用するモデルを作成します。
たとえばUserモデルでdeviseの認証機能を利用する場合は以下のコマンドを実行します。

$ rails g devise User

invoke  active_record
create    db/migrate/20200322122835_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

モデルの編集

rails g devise [モデル名]を実行するとdeviseという項目の付与されたモデルファイルが作成されます。利用するdeviseの機能(モジュール)のみを設定するように編集します。

各モジュールと概要は以下の通りです。1

モジュール 概要
database_authenticatable サインイン時のパスワードをハッシュ化して保存する
omniauthable OmniAuthのサポート機能を提供。SNS認証を実装する場合に利用する
confirmable メール認証の機能を提供
recoverable パスワードをリセットの機能を提供
registerable ユーザーのサインアップ、アカウントの編集や破棄の機能を提供
rememberable 認証情報を保存する機能を提供
trackable サインイン回数、タイムスタンプ、IPアドレスを追跡する機能を提供
timeoutable 一定時間活動していないアカウントのセッションを破棄機能を提供
validatable Emailやパスワードのバリデーションを提供します。
lockable 一定回数サインインを失敗するとアカウントをロックする機能を提供

今回はdatabase_authenticatableregisterableを利用するため、以下のように修正しました。

app/models/User.rb

class User < ApplicationRecord

-  devise :database_authenticatable, :registerable,
-         :recoverable, :rememberable, :validatable
+  devise :database_authenticatable, :registerable
end

マイグレーションファイルの編集

rails g devise [モデル名]を実行すると[日にち]_devise_create_[モデル名].rbという名前のマイグレーションが作成されます。
利用するdeviseモジュールに応じてファイルを編集します。

今回はdatabase_authenticatableregisterableを利用するので、マイグレーションファイルは以下のようになります。

# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
  end
end

マイグレーションの実行

マイグレーションファイル編集後、マイグレーションを実行します。

$ rails db:migrate

動作確認

deviseの認証機能が正常に動作しているか確認します。

レイアウトファイルの編集

認証状態を画面から確認できるようにするため、レイアウトファイルを編集します。

app/views/layouts/home.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>SimpleDevise</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

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

<body>
<header>
  <nav>
    <% if user_signed_in? %>
      <%= "こんにちは#{current_user.email}さん"  %>
      <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
    <% else %>
      <%= link_to 'サインアップ', new_user_registration_path %>
      <%= link_to 'ログイン', new_user_session_path %>
    <% end %>
  </nav>
</header>
<%= yield %>
</body>
</html>

サインアップの確認

Railsアプリケーションを再起動すると、localhost:3000/users/sign_up/users/sign_upで以下の画面が表示されます。

メールアドレスとパスワードを入力後ルート画面に遷移し、ヘッダにサインアップで利用したメールアドレスが記載されていればOKです。

認証情報の確認

deviseの認証情報はセッションで管理されています。
Railsアプリケーションではセッション情報はデフォルトでCookieに保存されています。

Cookieを確認すると、_[アプリケーション名]_sessionというセッション情報が保存されていることがわかります。
今回はアプリケーション名をsimple_deviseとしたので、_simple_devise_sessionという名前のセッションが保存されています。

セッション情報をもとに認証が行われているため、_[アプリケーション名]_sessionを削除してブラウザをリロードするとサインアウト状態になります。

まとめ

deviseのセットアップ手順
  1. 『devise:install』で設定ファイル作成
  2. 『devise:views』でビュー作成
  3. 『devise モデル名』でモデル作成
  4. モデル・マイグレーションのファイルを編集
  5. マイグレーション実行

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

Rubyのオススメ参考書


  1. https://github.com/heartcombo/devise