はじめに
「railsのアプリケーションで、ログイン認証機能をつけたいなー」
そんな時に使うのがdeviseというgemです。
今回は、deviseの導入方法から使い方を紹介します。
環境
Rails 6.1.4.1
アプリケーションの作成
まずは以下のコマンドで作成します。
$ rails new my_login_devise -d mysql
$ cd my_login_devise
今回はデータベースにMySQLを指定します。
コントローラー、ルートの設定
まずは以下のコマンドでデータベースを作ります。
$ rake db:create
次にコントローラーを作成します。今回はアクションも指定して以下のコマンドを打ちます。
$ rails g controller comments index
・rails g controller コントローラー名 アクション ‥このコマンドで、コントローラー作成と同時に、アクション、viewファイル、ルートの設定をしてくれます。
ただし、rootは手動で設定する必要があるので、以下のようにファイルに追記します。
Rails.application.routes.draw do
root 'comments#index' #この部分を追記
get 'comments/index' #コマンドで自動作成されたルート
end
deviseをインストール
まずはGemfileに以下を記述します。
gem 'devise'
以下のコマンドでインストール。
$ bundle install
次にdeviseを利用するのに必要な設定ファイルを作成します。*今回は使わない
以下のコマンドで作成。(devise専用コマンド)
$ rails g devise:install
ログイン機能用のモデルを作成
次に以下のコマンドでモデル(テーブル)を作成します。(今回はUserモデル)
$ rails g devise user
作成できたら、以下でデータベースに反映させます。
$ rake db:migrate
これで以下のような内容(カラム等)のデータベースが作成されました。
$ mysql -u root
mysql> SHOW COLUMNS FROM users FROM my_login_devise_development;
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| email | varchar(255) | NO | UNI | | |
| encrypted_password | varchar(255) | NO | | | |
| reset_password_token | varchar(255) | YES | UNI | NULL | |
| reset_password_sent_at | datetime | YES | | NULL | |
| remember_created_at | datetime | YES | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+------------------------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
view実装
以下のコマンドで、ログイン機能に必要なviewファイルをまとめて作成します。
$ rails g devise:views
上記で作成されたファイルの中でも、重要なのが以下の二つのファイルです。
新規登録画面:app/views/devise/registrations/new.html.erb
ログイン画面:app/views/devise/sessions/new.html.erb
ファイルを見てみると、すでにデフォルトの画面がコーディングされていることがわかります。
なので、トップページを編集して、これらの画面に遷移できるようにします。
views/comments/index.html.erb を以下のように編集します。
<h1>MY LOGIN</h1>
<% if user_signed_in? %> #①
<h4> メールアドレス: <%= current_user.email %> </h4> #②
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
<h2> 現在ログインしていません </h2>
<%= link_to "ログイン", new_user_session_path, class: 'post' %>
<%= link_to "新規登録", new_user_registration_path, class: 'post' %>
<% end %>
解説すると、
①のuser_signed_in?は、ログインしているかどうかを確認するdeviseのメソッドで、今回は、
ログインしていれば:メールアドレス、ログアウトのリンク
ログインしていなければ:「現在ログインしていません」、ログインのリンク、新規登録のリンク
を表示するようにしました。
②のcurrent_user.emailは、current_user.カラム名でログインしているユーザーのデータが取り出せるので、この場合emailを取得しています。
名前を追加する
deviseの初期設定では、emailとpasswordだけ登録できるようになっているので、追加で名前も登録できるようにします。
usersテーブルにnameカラムを追加
以下のコマンドで追加します。
$ rails g migration AddNameToUsers name:string
$ rake db:migrate
新規登録画面に名前のフォームを追加する
以下のファイルで、新規登録画面を編集します。
app/views/devise/registrations/new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
#ここから
<div class="field">
<%= f.label :name %> <br />
<%= f.text_field :name %>
</div>
#ここまで追記
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
データベースで保存できるようにする
deviseの初期段階では、メールアドレスとパスワードだけを受け取るように、ストロングパラメーターが設定されています。なので、deviseのストロングパラメーターを追加する必要があります。
そこで使うのが、追加をしてくれる、deviseのconfigure_permitted_parameters
メソッドです。
このメソッドを使って、application_controllerを以下のように編集します。
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
トップページに名前を表示
最後に、トップページにログインしている名前を表示するようにします。
<h1>MY LOGIN</h1>
<% if user_signed_in? %>
<h2> <%= current_user.name %> さんがログインしています </h2> #この部分追記
<h4> メールアドレス: <%= current_user.email %> </h4>
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
<h2> 現在ログインしていません </h2>
<%= link_to "ログイン", new_user_session_path, class: 'post' %>
<%= link_to "新規登録", new_user_registration_path, class: 'post' %>
<% end %>
立ち上げてみよう
以下のコマンドで、アプリを立ち上げます。
$ rails s
それぞれ以下のような画面になれば成功です。
・トップページ
・新規登録ページ
・ログインページ
・ログイン後のページ