Railsのメジャーなユーザー認証用gemである「Devise」が、1年以上の時を経てついにアップデートされました。
Rails7ではTurbo Streamが標準で有効化されているため、Deviseを導入する際にTurboが悪さをして不具合を引き起こしていました。
そのTurboの不具合対処のため、カスタムコントローラーを作成したりして色々と対処する必要があり、、正直かなり面倒でした。
ですが、今回のDeviseのアップデートにより、Rails7のTurboに標準で対応するようになりました。
これは嬉しい。
早速、最新版のDeviseをRails7に導入してみたので、忘備録として残しておこうと思います。
(Devise導入後のソースコードをこちらに載せておきます↓)
開発環境
- Ruby 3.1.2
- Ruby on Rails 7.0.4
- Devise 4.9.2
- tailwindcss 3.1.8
- M1 Macbook Air 2020
- mac OS Monterey (ver. 12.4)
- ターミナル bash (Rosetta 2 使用)
最新版 Devise を Rails7 に導入する流れ
最新版 Devise の導入方法は以下の公式githubの手順を参考にしています。
今回、改めてDeviseの導入手順についてまとめておきます。
Devise のインストール
まずはGemfile
に下記のように記述します。
gem 'devise'
以下のコマンドでgemをインストールします。
$ bundle install
続いて、以下のコマンドでDevise本体をインストールします。
$ rails g devise:install
Deviseのインストールが完了すると、ターミナルに以下のような表示が出ます。
===============================================================================
Depending on your application's configuration some manual setup may be required:
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.
* Required for all applications. *
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
* Not required for API-only Applications *
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>
* Not required for API-only Applications *
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
* Not required *
===============================================================================
Userモデルの作成
以下のコマンドでUserモデルを作成します。
$ rails g devise user
Userモデルを作成すると、db/migrate
以下にマイグレーションファイルが生成されます。
デフォルトではユーザー名カラムが作成されないため、必要であればマイグレーションファイルに追記します。
また、メール認証機能を有効化したい場合はConfirmable
の箇所をコメントアウトしておきます(以下を参照)。
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :name #←ユーザー名カラムを追加する場合は追記
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
# t.integer :sign_in_count, default: 0, null: false
# t.datetime :current_sign_in_at
# t.datetime :last_sign_in_at
# t.string :current_sign_in_ip
# t.string :last_sign_in_ip
# Confirmable ↓メール認証を利用する場合はConfirmableのコメントアウトを解除する
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
編集が完了したら、以下のコマンドでマイグレーションを実行します。
$ rails db:migrate
メール認証機能を有効化する(マイグレーションファイルのConfirmableをコメントアウトする)場合は、app/models/user.rb
に:confirmable
を追記します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable #←追記する
end
User、Adminなど複数モデルを作成したい場合は以下の記事を参考に進めてください。
Viewの追加
以下のコマンドを実行し、Devise用の各種フォームのViewファイルを作成します。
$ rails g devise:views
ただし、この場合app/views/devise
ディレクトリ以下にViewファイルが作成されることになるので、もしapp/views
以下のディレクトリをモデル名(User)と同じ名称にしたい場合は、以下のコマンドを実行します。
$ rails g devise:views users
こうすることでapp/views/users
ディレクトリ以下に各種Viewファイルが作成されます。
各種フォーム(新規登録、ログイン、パスワード再設定など)のカスタマイズをする場合はこれらのファイルを編集します。
「sign_up」「sign_in」へのリンクを貼る
適当なページに新規登録、ログイン、およびログアウト用のリンクを貼ります。
今回はトップページに貼ることにしましょう。
(ホームコントローラーを作成後、top.html.erbを追加しルートパスをhome#topとしておきます)
<h1>トップページ</h1>
<% if user_signed_in? %>
<div class="my-5">
<%= link_to "ログアウト", destroy_user_session_path, method: :delete, data: { turbo_method: :delete, turbo_confirm: "本当にログアウトしますか?" }, class: "font-semibold py-2 px-4 rounded text-white bg-sky-600 hover:bg-sky-800 cursor-pointer" %>
</div>
<% else %>
<div class="my-5">
<%= link_to "新規登録", new_user_registration_path, class: "font-semibold py-2 px-4 rounded text-white bg-sky-600 hover:bg-sky-800 cursor-pointer" %>
<%= link_to "ログイン", new_user_session_path, class: "font-semibold py-2 px-4 rounded border-2 hover:bg-gray-100 px-3" %>
</div>
<% end %>
リンクを貼ったら、実際に新規登録、ログイン、ログアウトができるかどうか試してみましょう。
メール認証を有効化する場合のメールサーバー設定
メール認証を有効化する場合(confirmableを設定した場合)は、使用するメーラーのアカウント登録、およびメールサーバー設定が必要になります。
ここではSendGridというメーラーを使う前提で話を進めて行きますが、SendGridは事前のアカウント登録とAPIキーの取得が必要です。登録における注意点もあるのでこちらで確認しておいてください。
(Gmailで設定したい場合は、アプリパスワード取得方法、およびメールサーバー設定でそれぞれ確認してください)
ちなみに、SendGridのアカウント登録については以下の記事が参考になります。
dotenv-railsの導入
メールサーバーの設定では、SendGridで取得したAPIキーを設定しますが、APIキーをそのまま設定ファイルに入力するのはセキュリティ上好ましくありません。
(SendGrid側も、生のパスワード使用を禁止しているみたいです)
アプリ内でAPIキーを使用する場合は、取得したAPIキーを環境変数として設定する必要があります。
以下、追加するGemはそのために必要なライブラリです。
gem 'dotenv-rails'
Gemを追記したら下記コマンドでインストールします。
$ bundle install
APIkey, Passwordなどを環境変数として設定(開発環境用)
アプリケーションフォルダ直下に.env
という名前のファイルを新規作成し、SendGridで取得したAPIキーを以下のように追加します。
# SendGridのAPIキー
SENDGRID_API_KEY = "SendGridのAPIキー"
また、APIキーをgithub上にアップしてしまわないように、.gitignore
に以下の1行を追記します。
/public/assets
# Ignore master key for decrypting credentials and more.
/config/master.key
# ↓最下部に追記
/.env
環境設定にメールサーバーの情報を記述
開発環境の場合、config/environments/development.rb
に以下のように記述します。
# SendGrid用のメールサーバー設定(開発環境)
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => 587,
:domain => 'localhost',
:user_name => 'apikey',
:password => ENV['SENDGRID_API_KEY'],
:authentication => :plain,
:enable_starttls_auto => true
}
:password
欄には環境変数として設定したAPIキーENV['SENDGRID_API_KEY']
を挿入します。
本番環境(Heroku)の場合はconfig/environments/production.rb
に以下のように記述します。
# SendGrid用のメールサーバー設定(本番環境→Heroku)
config.action_mailer.default_url_options = { host: 'https://Herokuのアプリ名.herokuapp.com' }
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => 587,
:domain => 'heroku.com',
:user_name => 'apikey',
:password => ENV['SENDGRID_API_KEY'],
:authentication => :plain,
:enable_starttls_auto => true
}
また、本番環境(Heroku)でも環境変数を利用できるようにするため、Heroku側で環境変数の設定を行います。
Herokuの対処アプリのSettingタブ > Config Vars
へ進み、以下のように環境変数のキーと値を入力します。
これでメールサーバーの設定は完了です。
ただし、SendGridの場合はアプリ側で「メールの差出人情報(送信元メールアドレス)」の設定もする必要があります。
(SendGridのアカウント作成後、送信元メールアドレスの登録&認証を済ませておく必要があります。送信元メールアドレスの登録&認証方法はこちらの②をご確認ください)
メールの差出人(送信元)情報の設定
送信元メールアドレスも環境変数として設定しておきたいので、
.env
ファイルを開き、SendGridで事前に認証済みの送信元メールアドレスを追記します。
# SendGridのAPIキー
SENDGRID_API_KEY = "SendGridのAPIキー"
# 送信元のメールアドレス(↓追記)
SENDER_ADDRESS = "送信元のメールアドレス"
次に、app/mailers/application_mailer.rb
のdefault from:
欄に先ほど環境変数として設定した送信元メールアドレスENV['SENDER_ADDRESS']
を追記します。
class ApplicationMailer < ActionMailer::Base
default from: ENV['SENDER_ADDRESS']
layout "mailer"
end
また、config/initializers/devise.rb
のconfig.mailer_sender
の箇所をコメントアウトし、以下のように編集します。
Devise.setup do |config|
・・・
# config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
# ↓以下のように変更
config.mailer_sender = ENV['SENDER_ADDRESS']
・・・
end
これで、アプリケーション側からメールが送信できるようになるはずです。
新規登録(sign_up)時に、登録したメールアドレス宛に以下のようなアカウント有効化リンクを含むメールが届いたら成功です。
アカウント有効化リンクをクリックすると、アプリ内にログインできるようになるはずです。
その他の設定
エラーメッセージ表示用のタグをapplication.html.erbに埋め込む
application.html.erb
の任意の場所に以下のタグを挿入します。
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
これで、タグを挿入した箇所にDeviseの確認メッセージ、およびエラーメッセージが表示されるようになります。
Deviseの各種メッセージを日本語化する
Deviseの確認メッセージおよびエラーメッセージはデフォルトで英語なので、これらを日本語化します。
まず、config/application.rb
に下記のコードを記述。
config.i18n.default_locale = :ja
config.time_zone = "Tokyo"
次にconfig/locales
内にdevise.ja.yml
およびja.yml
ファイルを作成します。
作成したファイルに翻訳データをコピーします。
devise.ja.yml
の翻訳ファイルはこちらから、ja.yml
の翻訳ファイルはこちらからそれぞれコピペします。
以上でDeviseの導入は完了です。
コメント