日々の反省

学んだことをつらつらと書いていきます。

Rails5でdeviseを利用したログイン認証を実装しておく


スポンサードリング

はじめに

何度も実装しているけど、コピーして済ましてきたdeviseの利用方法をまじめにまとめておくことにしました。

Gemfileの編集

まずはdeviseを追加します。

gem 'devise'

インストールしましょう。

bundle install

Deviseのインストール

それでは関連ファイルをインストールします。下記コマンドを実行します。

rails g devise:install

自分のcloud9の環境ではエラーが発生したため、解消するのにapplication.rbの以下の設定を削除しました。

module Workspace
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true
  end
end

上記のconfig.active_record.raise_in_transactional_callbacks = trueをコメントアウトします。

Deviseの設定

上記のインストール完了時点で英語のメッセージが表示されます。順番に対応していきます。

ActionMailerの設定

ActionMailerのデフォルトURLを変更してね。と言われているので変更します。 今回はGmailを利用するためconfig/environments/development.rbに以下のように追記しました。

Rails.application.configure do
  
(省略)
  
  # mailer setting
  config.action_mailer.default_url_options = {:protocol => 'https', :host => '[プロジェクト名].c9users.io' }
  
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => 'smtp.gmail.com',
    :port => '587',
    :domain => 'smtp.gmail.com',
    :authentication => 'plain',
    :user_name => '[メールアドレス]',
    :password => '[パスワード]'
  }
end

Cloud9を利用しているのでURLも変更しています。

ログイン後のページの作成

次にログイン完了後のページを作成しておきます。 今回はportalコントローラを作ってみました。

rails g controller portal index

ログイン後のページは認証後でないとアクセスできないようにするため コントローラに以下を追記します。

before_action :authenticate_user!

これによりログインしていない状態でアクセスするとログインページに遷移します。

flash messageの設定

ログイン成功/失敗時のメッセージ表示用にタグを追加します。 今回はapp/views/layouts/application.html.erbに以下のように記述しました。 BootstrapのCSSも追加しています。クローズボタン付きのアラート表示になります。

<% if notice %>
  <p class="alert alert-success alert-dismissible">
    <button type="button" class="close" data-dismiss="alert">
      <span aria-hidden="true">&times;</span>
      <span class="sr-only">close</span>
    </button>
    <%= notice %>
  </p>
<% end %>
<% if alert %>
  <p class="alert alert-danger alert-dismissible">
    <button type="button" class="close" data-dismiss="alert">
      <span aria-hidden="true">&times;</span>
      <span class="sr-only">close</span>
    </button>
    <%= alert %>
  </p>
<% end %>

Viewの生成

最後にDeviseのViewを生成して、カスタマイズ可能な状態にします。

rails g devise:views

モデルの作成

modelを作成します。今回は特にカスタマイズせずUserモデルを作成します。

rails g devise User
rake db:migrate

利用するモジュールを変えたい場合はマイグレーションする前に、マイグレーション用のファイルで コメントアウトされている各モジュール用の記述を変更してください。同時にmodelの変更もお忘れなく。今回は詳しく書きません。

ちなみに公式ドキュメントには以下のようにモジュールが説明されています。

  • Database Authenticatable: hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through
    POST requests or HTTP Basic Authentication.

  • Omniauthable: adds OmniAuth (https://github.com/omniauth/omniauth) support.

  • Confirmable: sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.

  • Recoverable: resets the user password and sends reset instructions.

  • Registerable: handles signing up users through a registration process, also allowing them to edit and destroy their account.

  • Rememberable: manages generating and clearing a token for remembering the user from a saved cookie.

  • Trackable: tracks sign in count, timestamps and IP address.

  • Timeoutable: expires sessions that have not been active in a specified period of time.

  • Validatable: provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.

  • Lockable: locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.

あー英語orz
なんとなく理解しましょう笑

Viewの編集

それでは次にログイン状態に応じたリンクの表示を定義します。 app/views/layouts/application.rbに以下を追加します。

  <nav class="navbar navbar-default">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#gnavi">
        <span class="sr-only">メニュー</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <% if user_signed_in? %>
        <a href="/portal" class="navbar-brand">Logo</a>
      <% else %>
        <a href="/" class="navbar-brand">Logo</a>
      <% end %>
    </div>
   
    <div id="gnavi" class="collapse navbar-collapse">
      <ul class="nav navbar-nav navbar-right">
      <% if user_signed_in? %>
        <li><%= link_to current_user.name, edit_user_registration_path, :class => 'navbar-link' %></li>
        <li></li>[<%= link_to 'ログアウト', destroy_user_session_path, method: :delete  %>]</li>
      <% end %>
      </ul>
    </div>
  </nav>

実際に必要なのは一部だけですが、ロゴとメニューを出してログイン済みであれば編集画面へ遷移する名前のリンクとログアウトを表示するようにしています。

ログインページの用意

ではログイン用のリンクを置くページを作ります。Welcomeコントローラを作成します。

rails g controller welcome index

app/views/welcome/index.html.erbにリンクを追加します。

<center>
  <div style="padding-top:50px">
    <p><%= link_to 'ログイン', new_user_session_path %></p>
  </div>
</center>

ログインページではログイン後とはちがうレイアウトを適用したいのでコントローラを編集します。 app/controllers/welcome_controller.rbを以下のように編集します。

class WelcomeController < ApplicationController
  layout "welcome"
  
  def index
  end
end

layoutにwelcomeを指定したのでapp/views/layouts/welcome.html.erbを作成します。

<!DOCTYPE html>
<html>
<head>
  <title>Lorica Task</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
  <%= csrf_meta_tags %>
</head>
<body>
<% if notice %>
  <p class="alert alert-success alert-dismissible">
    <button type="button" class="close" data-dismiss="alert">
      <span aria-hidden="true">&times;</span>
      <span class="sr-only">close</span>
    </button>
    <%= notice %>
  </p>
<% end %>
<% if alert %>
  <p class="alert alert-danger alert-dismissible">
    <button type="button" class="close" data-dismiss="alert">
      <span aria-hidden="true">&times;</span>
      <span class="sr-only">close</span>
    </button>
    <%= alert %>
  </p>
<% end %>
<div class="container">
<%= yield %>
</div>
</body>
</html>

config/routes.rbを修正してrootに指定しておきましょう。

Rails.application.routes.draw do
  root 'welcome#index'

 (省略)
end

動作確認

ここまでで一通りは完了です。deviseではユーザの登録・認証を簡単に実装することができます。 あとはサーバを動かして動作を確認してみてください。

その他

コントローラのカスタマイズを行いたい場合は以下のコマンドでコントローラを作成できます。今回はUserモデルを利用しているので「users」を指定しています。

rails g devise:controllers users

生成したコントローラを利用するためにはroute.rbの設定が必要です。

devise_for :users, :controllers => {
 :sessions => 'users/sessions'
}

上記の例ではログイン時のコントローラを変更しています。

さいごに

参考にしたのは以下のサイトです。それにしてもRailsは便利です。さっさとアプリを作って使って作ってを繰り返すには最適ですね。

github.com

[*Rails*] deviseの使い方(rails5版) - Qiita