Railsで何かしらのWebサイトを作る場合、大体は「認証機能(ログイン機能)」が必要になりますよね。
一から認証機能を作るとなると、実装やテストに多くの時間がとられるだけでなく、セキュリティの面から見ても不安が残ると思います。
そこで、おすすめなのが「devise」というgemパッケージです。
deviseを使うことで、誰でも簡単に安全な仕組みで、認証機能を実装できるようになります。
ここからは、そんなdeviseをRailsに導入する手順について、1つずつ丁寧に紹介していきたいと思います。
もくじ
deviseとは
deviseとは、Railsアプリケーションに認証機能を導入するためのgemパッケージです。
deviseを導入することで、以下のような機能が簡単に実装できるようになります。
- サインイン、サインアウト機能
- サインアップ機能(メール認証も可能)
- アカウント登録、編集機能
- パスワード変更、再発行機能
もちろん、各画面のデザインや制御のカスタマイズも可能です。
Railsにgemでdeviseを導入
ここでは、Railsにdeviseを導入にする手順を、以下のステップで進めていきます。
- deviseのインストール
- deviseの初期設定
- deviseの認証モデル作成
- devise用のデータを作成
- ブラウザから確認
deviseをgemでインストール
まずはdeviseをインストールしましょう。gem
を使えば簡単にインストールできます。
以下をGemfileに追記し、bundle install
を実行してdeviseをインストールしてみましょう。
gem 'devise'
$ bundle install
deviseの初期設定
deviseのインストールが終わったら、deviseの初期設定をしましょう。
初期設定は、rails g devise:install
を実行することで、関連ファイルが自動で作成されます。
$ rails g devise:install
Running via Spring preloader in process 85
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
===============================================================================
コマンドを実行すると、ファイル作成とともに上のような4つのステップが表示されます。
簡単にまとめると、以下のような内容になります。
- メールで使用するURLの設定
- ルーティングの設定
- 通知やアラートの表示用タグを追加
- Viewをカスタマイズする際のコマンド
1. メールで使用するURLの設定
deviseでは認証にメールを利用することができます。
その際、メールに記載されるデフォルトのURLをconfig/environments/development.rb
に設定しておく必要があります。
いますぐ設定しなくても動くので、とりあえずスキップして、あとから設定するのでもいいですよ。
Rails.application.configure do
:
:
# 認証メール内URL(例1)
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
# 認証メール内URL(例2)
config.action_mailer.default_url_options = { protocol: 'https', host: '192.168.99.100' }
end
2. ルーティングの設定
root to: "home#index"
のようなルートURLをconfig/routes.rb
で設定しておいてね!って書いてあります。
すでに設定している場合は不要ですし、あとから自分の好きな画面に設定したい場合は、とりあえずスキップしても問題ありません。
3. 通知やアラートの表示タグを追加
ログインやアカウント登録時の「通知」や「エラー」を表示できるように、以下の2つのタグをapp/views/layouts/application.html.erb
に追加する必要があります。
- <p class="notice"><%= notice %></p>
- <p class="alert"><%= alert %></p>
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>
4. Viewをカスタマイズする際のコマンド
deviseで利用する認証画面やアカウント登録画面などをカスタマイズをしたい場合は、rails g devise:views
を実行するよう書いてあります。
Viewのカスタマイズは、後ほど詳しく解説するので、とりあえずスキップしても大丈夫です。
deviseの認証モデルを作成
deviseの初期設定が終わったので、rails g devise モデル名
を実行して、「認証用モデル」と「マイグレーションファイル」を作成します。
これにより、指定したモデルでdeviseの認証機能が使えるようになります。ここでは「user」を指定しています。
$ rails g devise user
Running via Spring preloader in process 102
invoke active_record
create db/migrate/20190704023955_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
また、config/routes.rb
にdevise用のルーティングが自動で設定されているので確認します。
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
rails routes
を実行して、deviseのルーティングがどのように設定されたのかも確認しておきましょう。
$ rails routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
「/users/sign_in」がログイン画面、「/users/sign_up」はアカウント登録画面でルーティングされていることがわかると思います。
devise用のデータを作成
最後に、deviseによって自動作成されたマイグレーションファイルをDBに適用して完了です。
$ rails db:migrate
== 20190704031339 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.1317s
-- add_index(:users, :email, {:unique=>true})
-> 0.1135s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.1127s
== 20190704031339 DeviseCreateUsers: migrated (0.3600s) =======================
ブラウザから確認
これでdeviseを使った認証機能が利用できるはずです。
「http://IPアドレス/users/sign_in」にブラウザからアクセスして、上のような画面が表示されるか確認してみましょう。
もし、上のような「NoMethodError」や「Routing Error」が出ている場合は、Rails(Puma)を再起動させてからアクセスしてみてください。
deviseのメッセージを日本語化
このままdeviseを使ってもいいのですが、「デフォルトの表示を日本語化したい」という方もいるでしょう。
実は、deviseの日本語化パッケージを使えば、スマートに日本語化できます。
日本語化パッケージのインストール
まずは、Gemfileに以下を追記してgemパッケージをインストールしましょう。
gem 'devise-i18n'
gem 'devise-i18n-views'
$ bundle install
日本語ファイルを使用するように設定
次に、config/application.rb
を開いて、config.i18n.default_locale = :ja
を追加し、deviseの日本語化ファイルを読み込むように設定します。
$ require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module App
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.i18n.default_locale = :ja <(追加)
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
end
end
日本語ファイルを生成
最後に、rails g devise:views:locale ja
を実行して、deviseの日本語化ファイルを生成します。
$ rails g devise:views:locale ja
Running via Spring preloader in process 43
create config/locales/devise.views.ja.yml
これでdeviseの日本化は完了です。
ちなみに、自動生成された以下のconfig/locales/devise.views.ja.yml
を変更することで、表示される日本語メッセージのカスタマイズも可能です。
ja:
activerecord:
attributes:
user:
current_password: "現在のパスワード"
email: "メールアドレス"
password: "パスワード"
password_confirmation: "確認用パスワード"
remember_me: "ログインを記憶"
models:
user: "ユーザ"
devise:
confirmations:
new:
resend_confirmation_instructions: "アカウント確認メール再送"
mailer:
confirmation_instructions:
action: "アカウント確認"
greeting: "ようこそ、%{recipient}さん!"
instruction: "次のリンクでメールアドレスの確認が完了します:"
reset_password_instructions:
action: "パスワード変更"
greeting: "こんにちは、%{recipient}さん!"
instruction: "誰かがパスワードの再設定を希望しました。次のリンクでパスワードの再設定が出来ます。"
instruction_2: "あなたが希望したのではないのなら、このメールは無視してください。"
instruction_3: "上のリンクにアクセスして新しいパスワードを設定するまで、パスワードは変更されません。"
unlock_instructions:
action: "アカウントのロック解除"
greeting: "こんにちは、%{recipient}さん!"
instruction: "アカウントのロックを解除するには下のリンクをクリックしてください。"
message: "ログイン失敗が繰り返されたため、アカウントはロックされています。"
passwords:
edit:
change_my_password: "パスワードを変更する"
change_your_password: "パスワードを変更"
confirm_new_password: "確認用新しいパスワード"
new_password: "新しいパスワード"
new:
forgot_your_password: "パスワードを忘れましたか?"
send_me_reset_password_instructions: "パスワードの再設定方法を送信する"
registrations:
edit:
are_you_sure: "本当に良いですか?"
cancel_my_account: "アカウント削除"
currently_waiting_confirmation_for_email: "%{email} の確認待ち"
leave_blank_if_you_don_t_want_to_change_it: "空欄のままなら変更しません"
title: "%{resource}編集"
unhappy: "気に入りません"
update: "更新"
we_need_your_current_password_to_confirm_your_changes: "変更を反映するには現在のパスワードを入力してください"
new:
sign_up: "アカウント登録"
sessions:
new:
sign_in: "ログイン"
shared:
links:
back: "戻る"
didn_t_receive_confirmation_instructions: "アカウント確認のメールを受け取っていませんか?"
didn_t_receive_unlock_instructions: "アカウントの凍結解除方法のメールを受け取っていませんか?"
forgot_your_password: "パスワードを忘れましたか?"
sign_in: "ログイン"
sign_in_with_provider: "%{provider}でログイン"
sign_up: "アカウント登録"
unlocks:
new:
resend_unlock_instructions: "アカウントの凍結解除方法を再送する"
Viewをカスタマイズする場合
deviseでは、デフォルトの認証画面やアカウント登録画面をそのまま利用できるようになっています。
ですが、「自分でViewをカスタマイズしたい!」という場合もあると思います。
そんなときは、config/initializers/devise.rb
に以下のコードを追記し、カスタマイズを有効にします。
config.scoped_views = true
あとは、rails g devise:views users
を実行し、カスタマイズ用のViewテンプレートを作成しましょう。
この自動生成されたファイルを好きなように編集することで、各画面のカスタマイズが可能になります。
$ rails g devise:views users
Running via Spring preloader in process 41
invoke Devise::Generators::SharedViewsGenerator
create app/views/users/shared
create app/views/users/shared/_error_messages.html.erb
create app/views/users/shared/_links.html.erb
invoke form_for
create app/views/users/confirmations
create app/views/users/confirmations/new.html.erb
create app/views/users/passwords
create app/views/users/passwords/edit.html.erb
create app/views/users/passwords/new.html.erb
create app/views/users/registrations
create app/views/users/registrations/edit.html.erb
create app/views/users/registrations/new.html.erb
create app/views/users/sessions
create app/views/users/sessions/new.html.erb
create app/views/users/unlocks
create app/views/users/unlocks/new.html.erb
invoke erb
create app/views/users/mailer
create app/views/users/mailer/confirmation_instructions.html.erb
create app/views/users/mailer/email_changed.html.erb
create app/views/users/mailer/password_change.html.erb
create app/views/users/mailer/reset_password_instructions.html.erb
create app/views/users/mailer/unlock_instructions.html.erb
Controllerをカスタマイズする場合
Viewだけでなく、Controllerを変更してdeviseのデフォルトの動きを変更したい場合もあると思います。
これも同じようにrails g devise:controllers users
を実行して、生成されたファイルを編集することでカスタマイズできます。
$ rails g devise:controllers users
Running via Spring preloader in process 48
create app/controllers/users/confirmations_controller.rb
create app/controllers/users/passwords_controller.rb
create app/controllers/users/registrations_controller.rb
create app/controllers/users/sessions_controller.rb
create app/controllers/users/unlocks_controller.rb
create app/controllers/users/omniauth_callbacks_controller.rb
===============================================================================
Some setup you must do manually if you haven't yet:
Ensure you have overridden routes for generated controllers in your routes.rb.
For example:
Rails.application.routes.draw do
devise_for :users, controllers: {
sessions: 'users/sessions'
}
end
===============================================================================
deviseの使い方
deviseでは、頻繁に使うであろう関数があらかじめ用意されています。
これらの関数を使って、ログイン制御やユーザー情報の取得をおこないます。
# ログインユーザーのみアクセス許可(Controllerに記述)
before_action :authenticate_user!
# indexアクションはログインユーザーのみアクセス許可(Controllerに記述)
before_action :authenticate_user!, only: [:index]
# ユーザーがログイン済みかチェック
user_signed_in?
# ログインユーザーの情報を取得
current_user
# ユーザーのセッション情報を取得
user_session
まとめ
deviseを利用することで、Railsにサクッと認証機能を導入することができます。
認証機能の仕組みを知ることも大切ですが、時間を節約し効率よく開発することも大切です。
deviseには拡張性があり、カスタマイズするとさらに多くの時間が必要になってきますからね。
カスタマイズに関しては、勉強がてら自分で調べながら実装してみてください!
またね、キツネ(@kitaaaa_kitsune)でした!

