STEP21:Rails5にdeviseでログイン機能を実装しよう! #Rails #Ruby


今回は、Rails5にログイン管理機能ができるGemのdeviseを実装したいと思います。
ログイン管理というと、ユーザー登録と、登録時のメール認証、各ページの認証処理といった機能です。

Railsチュートリアルでは、学習の為、Gemを利用せずに自力で実装していますが、deviseのような便利なGemで簡単に実装する場合も多いので実際にやってみます。

全体の流れは、こんな感じ。

1)deviseの導入
2)設定ファイル
3)deviseのviewを生成
4)modelを生成
5)認証で利用するカラムを設定
6)ログアウトボタンを設置
7)未ログイン時の実装
8)メール送信の設定
9)アクセスして確認

1.deviseの導入

gem 'devise'

Gemfileに記述します。

$ bundle install --path vendor/bundle

bundle installをします。

$ bundle exec rails g devise:install

deviseの設定ファイルを生成します。

DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /pass/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:57)
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /assp/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:58)
      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

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

このように導入手順が出力されますので、その通りに設定を行っていきます。

2.設定ファイル

修正ファイル:config/environments/development.rb

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

デフォルトURLを、ひとまずlocalhostで設定します。
適当な場所に上記を追加します。

修正ファイル:config/routes.rb

root to: "top#index"

root_urlを設定します。

修正ファイル:app/views/layouts/application.html.erb

<% if notice %>
  <p class="notice"><%= notice %></p>
<% elsif alert %>
  <p class="alert"><%= alert %></p>
<% end %>

flashメッセージの設定。
認証時のflashメッセージを出力できるように、layouts(共通)のviewに下記を追加します。
今回は、の直下に追加しました。

3.deviseのviewを生成

$ bundle exec rails g devise:views

deviseのviewを制します。

DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /pass/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:57)
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /pass/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:58)
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/devise/shared
      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/password_change.html.erb
      create    app/views/devise/mailer/reset_password_instructions.html.erb
      create    app/views/devise/mailer/unlock_instructions.html.erb

実行すると上記のように、色々なファイルが出力されます。
名前から何となく、ユーザ登録用の画面や、パスワード変更時に利用するんだなということが分かります。

4.modelを生成

$ bundle exec rails g devise [モデル名]    

今回は、モデル名を「admin」とします。

DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /assp/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:57)
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /pass/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:58)
      invoke  active_record
      create    db/migrate/20160805044617_devise_create_admins.rb
      create    app/models/admin.rb
      invoke    rspec
      create      spec/models/admin_spec.rb
      invoke      factory_girl
      create        spec/factories/admins.rb
      insert    app/models/admin.rb
       route  devise_for :admins

こちらは、migrateファイルと、model、テストのファイルが生成されていることが分かります。

5.認証で利用するカラムを設定

修正ファイル:db/migrate/xxxxxxxxxxxx_devise_create_admins.rb

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

今回は、Confirmableと一緒にコメントアウトされていた4行のコメントを外して、有効にしました。

$ bundle exec rake db:migrate

migrateを実行して、DBに反映します。

6.ログアウトボタンを設置

修正ファイル:app/views/layouts/application.html.erb

<body>
  <% if admin_signed_in? %>
    <p><%= link_to "ログアウト", destroy_admin_session_path, method: :delete %></p>
  <% end %>
  <% if notice %>
    <p class="notice"><%= notice %></p>
  <% elsif alert %>
    <p class="alert"><%= alert %></p>
  <% end %>
  <%= yield %>
</body>

先ほど追加したflushを表示させるコードの上辺りに追加します。
admin_signed_in? この記述だけで、ログインの有無をチェックしてくれます。
ここは、お好きな箇所に挿入してください。

7.未ログイン時の実装

修正ファイル:app/controllers/application_controller.rb

before_action :authenticate_admin!

ログインされていなかったら、認証画面に画面遷移するように実装していきます。
下記を追記します。

修正ファイル:app/models/admin.rb

class Admin < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable
end

サインアップ時にメール認証をしたい場合は、下記に「:confirmable」を追加します。
既に、「:database_authenticatable」等設定されていますが、それぞれに利用できる機能があります。
例えば、「:database_authenticatable」は、アカウント登録時にパスワードを暗号化してDBに保存します。

8.メール送信の設定

修正ファイル:config/environments/development.rb

config.action_mailer.smtp_settings = {
  :enable_starttls_auto => true,
  :address => "smtp.gmail.com",
  :port => 587,
  :domain => 'smtp.gmail.com',
  :user_name => "xxxx@gmail.com", #gmailのアドレス
  :password => "xxxxxxxx",        #gmailのパスワード
  :authentication => 'login',
}

メール送信を行う場合は、上記を設定します。
二段階認証をしていない前提です。

9.アクセスして確認

$ bundle exec rails s

サーバを起動している場合は、再起動をしてください。
再起動を行わないと、メール送信がされません。

画面にアクセスしましょう。
http://localhost:3000/admins/sign_in

こんな画面が表示できて、アカウントの登録や、メール認証が出来たら成功です!
DeviseのTop画面

Ruby on Railsおすすめ書籍

Ruby on Railsの勉強で参考になった書籍です!

Ruby on Railsで質問したい!

Teratail(テラテイル)

WEBエンジニア専用のQ&Aサイトで、RubyやRailsも質問することができます。活発に質問と回答がされていますので、会員登録をして利用してみると良いと思います(^o^)。

エンジニアのためのQ&Aサイト【teratail】

Ruby on Railsが学べるオンラインスクール

好きな場所で好きな時間に受講できるオンラインスクール!最近は、Ruby on Railsも学ぶことができます!

TechAcademy(テックアカデミー)

オンラインでの週2回マンツーマンでのメンタリング、毎日15〜23時のチャット・レビューサポートで短期間で未経験からオリジナルサービスを開発できるようになる学習プログラム。オリジナルサービスをHerokuを使って公開するところまでを行います。

オンラインブートキャンプ Webアプリケーションコース