読者です 読者をやめる 読者になる 読者になる

Rails Webook

自社のECを開発している会社で働いています。Rails情報やサービスを成長させる方法を書いていきます

Railsのログイン認証gemのDeviseのインストール方法

Rails gem

https://camo.githubusercontent.com/b1c21cc10f2f94857dea5135fe55f2e4d451e028/68747470733a2f2f7261772e6769746875622e636f6d2f706c617461666f726d617465632f6465766973652f6d61737465722f6465766973652e706e67

概要

DeviseはRailsで最も人気なログイン認証機能を提供しているgemです。
RailsにDeviseのインストール方法を説明します。
また、初期設定、ログイン用のユーザーモデルを作成といったDeviseの導入部分を説明します。

動作確認

・Rails 4.1.4
・Devise 3.2.4


目次

  1. deviseのインストールと初期設定
  2. deviseのUserモデルの作成
  3. (おまけ) deviseの10個のモジュール説明
  4. (おまけ) よく使うdeviseのHelperメソッド

1. deviseのインストールと初期設定

まず、Railsプロジェクトの作成をします。

$ rails new devise
$ cd devise

次に、deviseをGemfileに追加します。

# Gemfile
gem 'devise'

そして、gemをインストールします。

$ bundle install

では、deviseに関連したファイルをRailsプロジェクトに追加します。

$ rails g devise:install
      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
   .......
   ......


5つの初期設定の方法が記載されたメッセージが表示されます。
これから、1つずつ実施していきましょう。

まず1番目。deviseのメール送信時のホスト名を指定します。

メール送信のために、config/environments/development.rb config.action_mailer.default_url_options = { host: 'localhost:3000' }を追加してください。
productionモードのときは、host:に実際のサーバーの値を設定して下さいと記載されています。

# config/environments/development.rb
Rails.application.configure do
  ...
  # deviseの設定
  config.action_mailer.default_url_options = { host: 'localhost:3000' }
end
次に2番目。root_urlを指定します。

deviseはログアウト時などのリダイレクト先としてroot_urlを使うため、これが設定されていないとエラーになってしまうため、設定しなければいけません。
既に設定されている場合は必要ありません。

# config/routes.rb
  ...
  root to: "home#index"
  ...

root_urlにルートを設定しましたが、実際のControllerやViewがないため作成しておきましょう。
home#indexを作成しましたのでルートにアクセスしても大丈夫です。
ここで、home#showも作成していますが、次の記事の「Deviseのカスタマイズ」の「アクセス制限」で使うため作っておきました。

$ rails g controller Home index show
      create  app/controllers/home_controller.rb
       route  get 'home/show'
       route  get 'home/index'
      invoke  erb
      create    app/views/home
      create    app/views/home/index.html.erb
      create    app/views/home/show.html.erb
      invoke  test_unit
      create    test/controllers/home_controller_test.rb
      invoke  helper
      create    app/helpers/home_helper.rb
      invoke    test_unit
      create      test/helpers/home_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/home.js.coffee
      invoke    scss
      create      app/assets/stylesheets/home.css.scss
次に3番目。エラーメッセージの表示領域を作成します。

deviseはログインやログアウトなどのときに、flashにサクセスやエラーメッセージを追加するので、その表示領域を追加します。

# app/views/layouts/application.html.erb
....
<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

<%= yield %>

</body>
</html>
4は、Rails3.2だけ必要なのでスキップします。
5は、Viewをカスタマイズしたいときのため必要であり、今はインストールのみのためスキップします。

次の記事の「Deviseのカスタマイズ」でDeviseのViewのカスタマイズを行います。

これで、deviseの初期設定は終わりました。

2. deviseのUserモデルの作成

それでは、deviseのモデルを作成しましょう。今回は、Userという名前でモデルを作成します。

$ rails g devise User
      invoke  active_record
      create    db/migrate/20140730042329_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

マイグレートする前に今作成された、user.rbyyyymmddhhmmss_devise_create_users.rbの中身を見ましょう。
deviseの重要なポイントとして、ModelファイルとMigrationファイルで10個のモジュールを有効/無効にできるからです。

まずは、user.rbを見ましょう。
デフォルトでは、いくつかのモジュールはコメントアウトされています。
これをコメントイン、コメントアウトすることにより、機能を有効/無効にすることができます。
それぞれのモジュールの説明は本ページ下部の「deviseの10個のモジュール説明」に記載してあります。

# app/models/user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

今度は、yyyymmddhhmmss_devise_create_users.rbを見ましょう。
「Database autohenticatbale」、「Recoverable」など見出しがついていることがわかると思います。先ほどの、Modelファイルでコメントインされているモジュールと対応させる必要があります。
例えば、user.rbで:confirmableをコメントインした場合、このマイグレーションファイルでもConfirmableの下の4行をコメントインしなければいけません。ちなみに、一番したの、confirmation_tokenのadd_indexメソッドもコメントインすることも忘れないで下さい。

# db/migrate/yyyymmddhhmmss_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end


とりあえず、今回は特に修正せず、マイグレートを実施します。

$ rake db:migrate

最後に、全ての画面の上部に、
・ログインしていない場合は、「サインイン」と「ログイン」のリンク
・ログインしている場合は、「プロフィール変更」と「ログアウト」のリンク
を表示させるようにします。

# app/views/layouts/application.html.erb
...
<body>
<header>
  <nav>
    <!-- user_signed_in? はユーザがログインしているか調べるdeviseのHelperメソッド -->
    <% if user_signed_in? %> 
      <!-- current_user は現在ログインしているUserオブジェクトを返すdeviseのHelperメソッド -->
      <!-- *_path はUserモデルを作成したときに、
        deviseにより自動で作成されてますので、rake routesで確認できます -->
      Logged in as <strong><%= current_user.email %></strong>.
      <%= link_to 'プロフィール変更', edit_user_registration_path %> |
      <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
    <% else %>
      <%= link_to "サインイン", new_user_registration_path %> |
      <%= link_to "ログイン", new_user_session_path %>
    <% end %>
  </nav>
</header>

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

<%= yield %>

</body>
</html>


では、サーバを起動し、画面を確認しましょう。

$ rails s

まず、ホーム画面(http://localhost:3000/)です。
f:id:nipe880324:20140731220850p:plain:w480

次に、サインアップ画面(ユーザ登録)(http://localhost:3000/users/sign_up)に遷移します。
f:id:nipe880324:20140731220852p:plain:w480

「Sign up」ボタンを押しました。すると、裏でユーザ登録とログイン処理が行われ、上記の表示が変わり、今登録したメールアドレスが表示されています。
f:id:nipe880324:20140731220853p:plain:w480

最後に、「ログアウト」をクリックしログアウトしています。
f:id:nipe880324:20140731220849p:plain:w480


deviseの導入はおしまいです。
次は、Deviseのカスタマイズ方法を見てくください。




(おまけ) deviseの10個のモジュール説明

deviseの公式ドキュメント(英語)に詳細は記載されています。

以下に、10のモジュールの日本語訳を記載しておきます(2014/8/1現在)

  • Database Authenticatable

サインイン中のユーザの認証を検証するために、パスワードの暗号とDBへの保存をします。
特殊な使い方をしない限り、基本的には必須。

  • Omniauthable

Omniauthサポートを追加します。
TwitterアカウントやFacebookアカウントなどでユーザ登録したい場合は、追加して下さい。

  • Confirmable

アカウントの有効化させるためのメールを送信し、そして、サインイン時(ユーザ登録)にアカウントが有効化されているか検証する。
サインインプロセスを、ユーザに確認メールを送信して、そのメール内のリンクをクリックしないとアカウントが有効化されない(ログインできない)というプロセスにできます。
これが無い場合は、サインインを行ったら、すぐにログインができます。

  • Recoverable

パスワードを忘れたときのための、パスワードのリセットができるようになります。

  • Registerable

サインアップ処理によってユーザアカウントを行うことができます。アカウントの編集や削除も含まれています。
特殊な使い方をしないかぎり、基本的には必須だと思います。

  • Rememberable

クッキーに保存されたトークンの生成と削除を行うことができます。
あまり良くわかっていませんが、デフォルトでもコメントインされているので多分必須だと思います。

  • Trackable

サインインの回数やサインイン時刻、IPアドレスをDBのカラムに保存します。

  • Timeoutable

指定した一定時間内に操作がなければセッション情報を削除できます。

  • Validatable

メールアドレスとパスワードの基本的な検証をします。自分自身でValidationも追加できます。

  • Lockable

指定した回数サインインに失敗した場合にアカウントをロックされます。指定した時刻経過するか、メールによってアンロックができます。



(おまけ) よく使うdeviseのHelperメソッド

#下記の'_user'はモデル名に依存する。つまり、モデル名が'admin'ならば、current_adminなどと記載する必要がある。

# ユーザがログインしていないとアクセスできない(Controllerに記載)
before_action :authenticate_user!

# ユーザがサインインしているか調べる
# 返り値は、true か false
user_signed_in?

# サインインしているユーザオブジェクトを取得する
current_user

参考文献


良く分からない、間違っている箇所などありましたら、お気軽に以下のコメント欄に記載ください。直に返します。