はじめに
Railsアプリに認証機能を導入するには「devise」というGemを使う方法が最も簡単です。「devise」は認証に係る機能をほとんどコードを書くことなく実装できる反面、処理がブラックボックス化されており、全容が把握しづらいというデメリットがあります。Railsで初めて認証機能を導入する場合、まずは簡単な認証機能を自分で実装し、認証機能に関する理解を深めておくことをおすすめします。認証機能を自分で実装する方法については以下の記事を参照してください。
本記事では、「devise」を使った認証機能の実装について説明します。
「devise」の基本的な使い方
「devise」のインストール
「devise」をインストールするには、Gemfile
に以下を追記し、bundle install
を実行します。
Gemfile
gem 'devise'
次に、ターミナルで以下のコマンドを実行します。
$ rails generate devise:install
上記のコマンドを実行すると以下のファイルが作成されます。
ファイル | 説明 |
---|---|
config/initializers/devise.rb |
「devise」の設定ファイル。 |
config/locales/devise.en.yml |
「devise」の言語ファイル(英語)。 |
また、初めに行っておく必要のある設定などについて指示されるので、指示に従って設定を行います。
デフォルトURLの設定
「devise」では、ユーザー登録を行う際に入力したメールアドレスにメールを送り、本登録を完了させるという機能を追加することができます。その際、メールに記載するURLのドメイン名をあらかじめ設定しておく必要があります。
開発環境の場合、config/environments/
ディレクトリ配下のdevelopment.rb
ファイルに以下を追記します。
development.rb
Rails.application.configure do
# 以下を追記
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
本番環境の場合、config/environments/
ディレクトリ配下のproduction.rb
ファイルに上記の開発環境と同じ設定に対し、ご自分のドメイン名とポートを設定します。以下は設定例です。
production.rb
Rails.application.configure do
# 以下を追記
config.action_mailer.default_url_options = { host: 'www.example.com', port: 80 }
end
ルートルーティングの設定
「devise」は、ユーザー登録の完了時やパスワードの変更後にデフォルトのリダイレクト先としてルートに遷移するようになっています。デフォルトのリダイレクト先を変更しない場合は、ルートのルーティングを設定しておく必要があります。
$ rails generate controller Statics index
routes.rb
Rails.application.routes.draw do
# 以下を追記
root 'statics#index'
end
デフォルトのリダイレクト先を変更するには、後述する「リダイレクト先の変更」セクションを参照してください。
フラッシュメッセージの表示
「devise」は、ログイン/ログアウト成功時などにフラッシュメッセージを設定します。必須ではありませんが、それらのフラッシュメッセージの表示を設定しておきます。以下はレイアウトにフラッシュメッセージを設定する例です。
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>RailsDevise</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%# 以下を追記 %>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>
モデルの作成
「devise」で使用するモデルを作成します。モデル名は通常User
にしますが、これ以外のモデル名にすることもできます。
$ rails generate devise User
上記のコマンドを実行すると、モデルの作成、マイグレーションファイルの作成、ルーティングの追加などが行われます。モデルやマイグレーションには様々なオプションが用意されており、コメントアウトを外し有効にすることでオプションの機能を追加することができます。
モデルおよびマイグレーションの必要な機能を有効にしたら、以下のコマンドを実行します。
$ rails db:migrate
これで「devise」の基本的な機能を使用する準備ができました。
ヘルパーメソッド
「devise」にはコントローラーやビューで使用する様々なヘルパーメソッドが用意されています。なお、以下はモデル名をUser
とした場合の例です。例えば、モデル名がMember
の場合、ヘルパーメソッドはauthenticate_member!
のようになります。
ヘルパーメソッド | 説明 |
---|---|
authenticate_user! |
このヘルパーメソッドを設定したアクションが実行されるとき、ユーザーがログインしていなければログイン画面に遷移する。 |
user_signed_in? |
ユーザーがログインしているかどうかを判定する。 |
current_user |
現在ログインしているユーザー情報を取得する。 |
user_session |
現在ログインしているユーザーのセッションを取得する。 |
authenticate_user!
の使い方は以下の通りです。
users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:show, :edit, :update, :destroy]
# アクションは省略
end
「devise」のカスタマイズ
「devise」の日本語化
「devise」で作成されたフォームやフラッシュメッセージを日本語化するには、config/
ディレクトリ配下のapplication.rb
に以下を追記します。
application.rb
module RailsDevise
class Application < Rails::Application
# 以下を追記
config.i18n.default_locale = :ja
end
end
次に、Gemfile
に以下を追記しbundle install
を実行します。
Gemfile
# 以下を追記
gem 'devise-i18n'
一部の文言だけ変更したい場合は、config/locale/
ディレクトリ配下にdevise.ja.yml
ファイルを作成し、変更したい文言とその訳を追記します。利用可能な文言は同ディレクトリ配下にあるdevise.en.yml
を参照してください。
devise.ja.yml
ja:
devise:
sessions:
signed_in: "ログインに成功しました。"
signed_out: "ログアウトに成功しました。"
ルーティングの変更
デフォルトのルーティングを変更したい場合、devise_for
メソッドのオプションを使用します。
routes.rb
Rails.application.routes.draw do
devise_for :users, path: 'auth', path_names: [sign_in: 'log_in']
end
上記のようにオプションを追加すると、ログイン画面のルーティングは/users/sign_in
から/auth/log_in
に変更されます。特定のルーティングを/sign_in
のようにしたいなど、より詳細な変更が必要な場合、devise_scope
ブロック内に通常のルーティングを記述します。
routes.rb
Rails.application.routes.draw do
# 以下は残す
devise_for :users
# 以下を追記
devise_scope :user do
get '/sign_in', to: 'users/sessions#new'
end
end
上記のように設定すると、/users/sign_in
の他に/sign_in
も使えるようになります。devise_for
を削除してしまうと、devise_scope
ブロック内のルーティング以外が使えなくなるのでご注意ください。
カスタムビューの作成
ユーザー登録画面やログイン画面を変更したい場合、カスタムビューを作成します。
$ rails generate devise:views users
上記のコマンドを実行すると、app/views/users/
ディレクトリ配下に「devise」で使用するすべてのビューが作成されます。特定のビューのみ作成したい場合は-v
オプションを使用します。
$ rails generate devise:views users -v sessions registrations
カスタムビューが存在しない場合はデフォルトのビューが使用されます。
カスタムコントローラーの作成
「devise」の処理を変更したい場合、カスタムコントローラーを作成します。
$ rails generate devise:controllers users
上記のコマンドを実行すると、app/controllers/usres/
ディレクトリ配下に「devise」で使用するすべてのコントローラーが作成されます。特定のコントローラーのみ作成したい場合は-c
オプションを使用します。
$ rails generate devise:controllers users -c sessions registrations
カスタムコントローラーやカスタムアクションが存在しない場合はデフォルトのコントローラーやアクションが使用されます。
作成したカスタムコントローラーを使用するようルーティングを変更します。
routes.rb
Rails.application.routes.draw do
# 以下を修正
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
end
ストロングパラメーターの追加
カスタムビューを作成し、ユーザー登録画面などのパラメーター(IDやパスワードなど)を追加する場合、ストロングパラメーターを追加する必要があります。ストロングパラメーターを追加するには、application_controller.rb
に以下を追記します。
application_controller.rb
class ApplicationController < ActionController::Base
# 以下を追記
before_action :configure_sign_up_parameters, if: :devise_controller?
protected
def configure_sign_up_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:user_name])
end
end
カスタムコントローラーに追加することもできます(カスタムコントローラーを作成している場合)。
registratioins_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
# 以下を追記
before_action :configure_sign_up_parameters, only: [:create]
protected
def configure_sign_up_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:user_name])
end
end
リダイレクト先の変更
ユーザー登録/解除、ログイン/ログアウトが成功したときのデフォルトの遷移先はルートです。これらのリダイレクト先を変更することができます。ユーザー登録/解除とログイン/ログアウトで変更方法が異なるので分けて説明します。
ユーザー登録/解除のリダイレクト先
以下のコマンドを実行して、「devise」のカスタムコントローラーを作成します。
$ rails generate devise:controllers users
app/controllers/users/
ディレクトリ配下のregistrations_controller.rb
を以下のように修正します。
registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
# 以下のコメントアウトを外す
# The path used after sign up.
def after_sign_up_path_for(resource)
# 以下を修正
user_path
end
# The path used after sign up for inactive accounts.
def after_inactive_sign_up_path_for(resource)
# 以下を修正
new_user_registration_path
end
end
次に、routes.rb
を以下のように修正します。
routes.rb
Rails.application.routes.draw do
# 以下を修正
devise_for :users, controllers: {
registrations: 'users/registrations'
}
end
ログイン/ログアウトのリダイレクト先
application_controller.rb
に以下を追記します。
application_controller.rb
class ApplicationController < ActionController::Base
# 以下を追記
def after_sign_in_path_for(resource)
user_path
end
def after_sign_out_path_for(resource)
new_user_session_path
end
end
after_sign_in_path_for
メソッドおよびafter_sign_out_path_for
メソッドは「devise」で実装しているメソッドです。これらのメソッドをオーバーライドしています。
確認メール送信設定
ユーザー登録時に入力されたメールアドレスに確認メールを送信し、メールアドレスの認証を行う機能を追加します。なお、以下の手順は送信元メールにGmailを使用する場合の例です。
カラムの追加
確認メールで使用するカラムをテーブルに追加します。
yyyymmddhhmmss_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
...
## Confirmable
# 以下のコメントアウトを外す
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
...
end
end
end
テーブル作成後にカラムを追加したい場合、カラム追加のマイグレーションを作成します。
$ rails generate migration add_confirmable_to_users
yyyymmddhhmmss_add_confirmable_to_users.rb
class AddConfirmableToUser < ActiveRecord::Migration[6.1]
def change
# 以下を追記
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
end
end
マイグレーションが用意できたら以下を実行します。
$ rails db:migrate
モデルの変更
確認メールを送信する設定をモデルに追加します。
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
# 以下を追記
:confirmable
end
メール送信の設定
まず、メール送信設定で使用する機密情報をCredentialsに登録します。
$ EDITOR=vi rails credentials:edit
google:
mail: YourMailAddress
password: YourPassword
メールアドレスにGmailを使用する場合、アプリパスワードの設定が必要になります。アプリパスワードの設定については以下の記事の「アプリ パスワードを作成、使用する」セクションを参照してください。
config/initializers/
ディレクトリ配下のdevise.rb
を以下のように修正します。
devise.rb
Devise.setup do |config|
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
# 以下を修正
config.mailer_sender = Rails.application.credentials.google[:mail]
end
config/environments/
ディレクトリ配下のdevelopment.rb
に以下を追記します。
development.rb
Rails.application.configure do
# 以下を追記
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => Rails.application.credentials.google[:mail],
:password => Rails.application.credentials.google[:password],
:authentication => :plain,
:enable_starttls_auto => true
}
end
以上で確認メール送信設定は完了です。なお、確認メール送信設定を行う以前に登録していたアカウントについては、ログインする際にメールアドレスの確認が必要になっています。その場合は確認メールの再送信を行ってください。
まとめ
認証機能を導入するだけなら「devise」は最も簡単な方法のひとつです。しかし、実際には「devise」のデフォルトセットでは物足りないという場合が多く、いくつかの追加の機能を実装する必要が出てくるかもしれません。その際、一度認証機能を自分で実装しているとその経験がきっと役に立つはずです。
本記事を参考にして、「devise」を使って認証機能を実装していただければと思います。