deviseを使用し、ユーザー認証を実装する

Railsで作成したwebアプリケーションに簡単に認証機能(ログイン機能)を実装できるgemである「devise」を使用し、ユーザー認証機能とユーザーページを作成しました。

以下は作成済みの新規アプリケーションがあることが前提です。

学んだこと✏️

1.devise gemをインストール

Gemfilegem 'devise'を追記し、$ bundle install

2.初期設定(アプリケーションのルートディレクトリで)
`rails g devise:install`

このコマンドで関連ファイルが自動作成される。また、ファイル作成とともに以下の4つのステップが表示される。

①メールで使用するURLの設定(config/environments/development.rb)

②ルーティングの設定(config/routes.rb)

③通知やアラートの表示タグを追加(app/views/layouts/application.html.erb)

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

Railsにdeviseをサクッと導入!認証機能の使い方も解説【日本語化】 | キツネの惑星

3.deviseの認証モデルを作成、データ作成

rails g devise モデル名を実行。
「認証用モデル」と「マイグレーションファイル」を作成。config/routes.rbにdevise用のルーティングが自動で設定されているのを確認後$ rails db:migrate

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

GitHub - heartcombo/devise: Flexible authentication solution for Rails with Warden.

4.パスワード再設定機能を実装

config/environments/development.rb(環境ごとの設定ファイル)に以下を追加し、パスワード再設定時に送信されるメールに含まれるURLを正しく生成する。

 config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  • パスワード再設定用のビューを作成。それぞれパスワード再設定メールの送信、パスワード再設定フォームを表示。

    • app/views/devise/passwords/new.html.erb
    • app/views/devise/passwords/edit.html.erb
  • rails routesでルーティングの確認。コントローラーとアクション名の組み合わせが、devise/passwords#アクション名になっている部分が使用するルーティング。

  • パスワード再設定のためのメールテンプレートを作成。

    • app/views/devise/mailer/reset_password_instructions.html.erbを作成し、パスワード再設定用のメールを表示。
5.ログイン画面に遷移するよう設定

app/controllers/application_controller.rbに以下を追記。 これにより、ログインしていない時のアクセスは全てログイン画面に遷移する。(devise のモデルが 'User' であると仮定)

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
end

GitHub - heartcombo/devise: Flexible authentication solution for Rails with Warden.

6.サインアップとログインリンクの追加

app/views/layouts/application.html.erbにアカウント編集とログアウトのリンクを追加。

Rails Girls - Japanese

7. ユーザー一覧・詳細画面を作成

以下のコマンドを実行し、Userテーブルにnamepostal_codeaddressself_intrroductionカラムを追加。 注意点として、postal_codeを数値扱い(integer)にすると、0からはじまる郵便番号をいれると0が省略されてしまう。

$ rails g migration AddColumnsToUsers name:string postal_code:string address:text self_introduction:text
$ rails db:migrate

config/routes.rbに以下のルーティングを追加。

resources :users, only: %i[index show]

rails routesを実行し、users#index, users#showのルーティングが追加されたことを確認。

       :
users GET    /users(.:format)   users#index
user GET    /users/:id(.:format)   users#show

以下のコマンドを実行し、usersコントローラーを作成。

$ rails g controller users index show --skip-routes --no-helper --no-assets --no-test-framework

生成されたapp/controllers/users_controller.rbを編集。

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end
end

ユーザ一ー覧画面(app/views/users/index.html.erb)を編集。

<h1>All users</h1>

<table>
  <thead>
    <tr>
      <th>email</th>
      <th></th>
    </tr>
  </thead>

  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.email %></td>
        <td><%= link_to 'detail', user %></td>
      </tr>
    <% end %>
  </tbody>
</table>

ユーザー詳細画面(app/views/users/show.html.erb)を編集。

<p>
  <strong>email</strong>
  <%= @user.email %>
</p>

<p>
  <strong>postal_code</strong>
  <%= @user.postal_code %>
</p>

<p>
  <strong>address</strong>
  <%= @user.address %>
</p>

<p>
  <strong>self_introduction</strong>
  <%= @user.self_introduction %>
</p>

<%= link_to 'back', users_path %>
8.サインアップ画面とアカウント編集画面を編集

Gemfileにgem 'devise-i18n'を追記し、$ bundle installを実行してdevise-i18nをインストール。

以下のコマンドを実行して、devise:i18n:viewsを生成。

$ rails g devise:i18n:views -v registrations

アカウント編集ページ(app/views/devise/registrations/edit.html.erb)を編集し、app/controllers/application_controller.rbに以下を追記。

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:account_update, keys: [:postal_code, :address, :self_introduction])
  end
end

上記により、ユーザー登録時 (Devise::RegistrationsController#create)とアカウント編集時(Devise::RegistrationsController#update)のみ postal_codeカラムとaddressカラムとself_introductionカラムの更新を許可する。これにより、セキュリティ上のリスクを軽減し、不正なパラメータの送信を防ぐことができる。

Strong Parameters

9.ユーザー一覧にページングを追加。

前回学習したページング処理もユーザー一覧ページに追加。
kaminari を使ってページング処理を実装 - なつログ

app/controllers/users_controller.rb

def index
  @users = User.order(:id).page(params[:page])
end

app/views/users/index.html.erb

<%= paginate @users %>
10.サインイン,サインアウト,アカウント編集後のリダイレクト先の変更

app/controllers/application_controller.rbに以下を追記。

class ApplicationController < ActionController::Baseprivate

  def after_sign_in_path_for(_resource)
    books_path
  end

  def after_sign_out_path_for(_resource)
    new_user_session_path
  end

  def signed_in_root_path(_resource)
    user_path(current_user)
  end
end

Controller filters and helpers - devise

11.deviseのメッセージを日本語化
  • config/application.rbconfig.i18n.default_locale = :jaを追加し、日本語ファイルを使用するように設定。

  • 共通する箇所と各画面を日本語に変更する。

  • 日本語ファイルを生成

    • rails g devise:views:locale jaを実行し、deviseの日本語化ファイルを生成。
  • 自動生成されたconfig/locales/devise.views.ja.ymlを変更することで表示される日本語メッセージのカスタマイズも可能。

12.最後に、letter_opener_web gemを使用し、送信したメールをブラウザ上で確認する

letter_opener_webは、Railsアプリケーションでメールを開発時にブラウザでプレビューするためのGem。 開発中に実際にメールを送信するわけではなく、開発環境内でメールをプレビューできる。 これにより、実際にメールを送信することなく、メールの表示とレイアウトを確認することができる。

Gemfileにletter_opener_webを追加しインストール。

group :development do
  gem 'letter_opener_web', '~> 2.0'
end

ルーティングの追加。

Rails.application.routes.draw do
       :
  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
end

config/environments/development.rbファイルに以下のコードを追加。

Rails.application.configure do
       :
  config.action_mailer.delivery_method = :letter_opener_web
  config.action_mailer.perform_deliveries = true
end

config/initializers/devise.rbconfig.mailer_senderを変更する。 これはDeviseで使用されるメール送信者のメールアドレスを設定するためのオプション。please-change-me-at-config-initializers-devise@example.comは、このオプションの初期値として提供されるダミーのメールアドレスのため変更した方が良い。Deviseが生成する各種メールで使用されるFromヘッダーにこの設定されたメールアドレスが使用される。したがって、メールの受信者は、このアドレスからメールを受信した場合に、誰からのメールであるかを識別することができる。

       :
config.mailer_sender = 'info@example.com'
  • ブラウザでhttp://localhost:3000/letter_openerにアクセス。 このページでは、開発環境で作成されたメールを確認することができる。

letter_opener_web

まとめ

初見でしたので難しく感じましたが、今後頻繁に実装する機能だと思うのでスムーズに実装できるようになっていきたいです!