#deviseとは
この記事では、railsでのdeviseを使ったログイン認証機能の実装について、備忘録として書き残すことにする。
なお、下記のページを参考にさせていただきました。
-
Rails deviseによるユーザー認証 メールによる認証、emailとusernameのどちらでもログイン可能にするまで
-
How-Tos
#実行環境
ruby 2.3.0p0
rails 5.1.4
devise 4.3.0
#とりあえず動くようにする
はじめにgemをインストール。
# 以下を追加
gem 'devise'
bundle install
一通り機能をインストールする。
rails g devise:install #全体のインストール
rails g devise user #ユーザーモデルを作成
rake db:migrate #userテーブルを作成
rails g devise:views #ビューの作成
なお、devise:installした時に、いくつか指示が出ている。まず下記をconfigファイルに追記。自分の環境では大体30行目くらいに入れました。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
この時点でルーティングまで自動で行われているが、ルートの設定ができていることを確認しておく。
devise_for :users #自動で挿入されている
root 'blogs#index' #それぞれのパスに設定
下記のflashメッセージも追加。とりあえずbodyの真下としておく。
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
#望み通りの仕様にカスタマイズする
このままだとまだまだ実用に程遠いので、カスタマイズしていく。
ユーザー認証にすると同時に自動的にやっておいた方がいいよねこれっていう機能は割と多いように思う。
本記事の中では、デザインの部分(CSS周り)はとりあえず無視します。
ユーザーのログイン状態を判定し、ルーティング先を変更
たいていの場合、ページに飛んできた人がすでにログイン状態かどうかを判定して、
- ログイン状態であればリクエストのコンテンツを表示
- ログイン状態でなければログインページ、もしくはサインアップのページに飛ぶ
という操作となると思う。それの実装。と言ってもdeviseにすでにそれ用のヘルパーが定義されている。
before_action :authenticate_user! #protect_from_forgery with: :exceptionより後におく。
アプリ全体の仕様にしたかったのでapplicationに記載。そうでなければ、それぞれのコントローラに仕込む。
実装の確認のために、ログアウトのリンクを仕込んでおく。
#以下を適当なところに追記
<% if user_signed_in? %>
<p><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></p>
<% end %>
これでログイン時はリクエストしたページへ通し、ログオフ時はログイン画面に弾くようになった。そしてそれを確認。
メール認証
サインアップしたユーザーアカウントは、一旦仮登録としてメールを飛ばし、返信を持って本登録とするあれ。
ステップは次の通り。
Userモデルにconfirmableを追加。これで各種認証時に「確認作業」が定義できるようになる。Eメール認証はそのやり方のうちの一つ、くらいで認識している。
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable #最後のやつを追加
Userテーブルに確認にまつわる項目を追加しなければいけないようだ。マイグレーションファイルを作成。
rails g migration add_confirmable_to_devise
マイグレーションファイルを次のようにする。ここは、上記参考ページのままコピペ。reconfirmbleも設定したい人は、コメント外した方がいい行がいくつかある。関係ないのでこのままでいく。
class AddConfirmableToDevise < ActiveRecord::Migration[5.1]
# Note: You can't use change, as User.update_all will fail in the down migration
def up
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
# add_column :users, :unconfirmed_email, :string # Only if using reconfirmable
add_index :users, :confirmation_token, unique: true
# User.reset_column_information # Need for some types of updates, but not for update_all.
# To avoid a short time window between running the migration and updating all existing
# users as confirmed, do the following
User.all.update_all confirmed_at: DateTime.now
# All existing user accounts should be able to log in after this.
end
def down
remove_columns :users, :confirmation_token, :confirmed_at, :confirmation_sent_at
# remove_columns :users, :unconfirmed_email # Only if using reconfirmable
end
end
rake db:migrate
これで、Eメール送信のための設定は済んだわけですが、肝心のSMTPサーバの設定が必要。うっかりgithubにアップしたくはないから、letter-opener_webを使うことにする。まずはgemをインストール。
group :development do #開発環境のみ
gem 'letter_opener_web'
end
bundle install
以下をルーティング設定に追加。
if Rails.env.development? #開発環境の場合
mount LetterOpenerWeb::Engine, at: "/letter_opener"
end
メールの送信にletter_opener_webを使用する。
#以下を追記(config.action_mailer.default_url_optionsの直下あたりがしっくりくるか)
config.action_mailer.delivery_method = :letter_opener_web
これでメール送信の設定は全て終了。メール認証が実装できていることを確認できると思いきや、エラーが発生した。原因はテーブルでコメントのままだった下記の2行のようだ。アンコメントして、migrationし直したらEメール認証できるようになった。
class AddConfirmableToDevise < ActiveRecord::Migration[5.1]
# Note: You can't use change, as User.update_all will fail in the down migration
def up
#(省略)
add_column :users, :unconfirmed_email, :string # Only if using reconfirmable
#(省略)
end
def down
#(省略)
remove_columns :users, :unconfirmed_email # Only if using reconfirmable
end
end
管理者権限の設定
複数のユーザーがサービスを用いる場合、普通は管理者権限を設定し、特殊な操作は管理者のみ実行可としておく。
rails generate migration add_admin_to_users admin:boolean
add_column :users, :admin, :boolean, default: false
デフォルト値は当然のごとくfalse。trueだと基本みんな管理者になってしまう。
あとは次のように管理者しかできないアクションを定義してやれば良い。
if current_user.admin? # current_userメソッドがnilとなるページも考慮し、current_user.try(:admin?)でもいいらしい
#do something
end
#終わりに
ということで、deviseの導入によるユーザー認証機能とそれに伴う設定をいくつかやりましたが、ルーティングの設定などは細かく定義できますし、facebookアカウントでの認証などの機能もありますね。やろうと思えば山積みです。
もっと簡単にできるとかそもそも間違っているとかがありましたら、ご指摘願えれば幸いです。