前回の記事ではRailsアプリにdeviseを使ってユーザーページを追加しました。
今回はdeviseが用意してくれているrecoverble
モジュールを使ってメール認証を使ったパスワード再設定機能を追加します。
実装対象のアプリはdeviseを使ってログイン機能を実装する記事で使用したアプリです。
実装は次の手順で行います。
- recoverbleモジュールの有効化を確認
- Gmailのアプリパスワードを発行
- dotenv gemを使用してメールアドレスとアプリパスワードを環境変数化
- メール送信用サーバをGmail用に設定
- 送信元のメールアドレス設定
1. recoverbleモジュールの有効化を確認
devise gemのセットアップ時にrecoverble
モジュールはデフォルトで有効化されています。
認証機能を追加したモデルを確認することでモジュールの追加を確認できます。
# app/models/user.rb class User < ApplicationRecord ... # ↓recorvebleモジュールが有効になっている devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end
また、deviseセットアップ時のマイグレーションファイルにもrecorveble
モジュールが有効化されているか確認します。
# db/migrate/xxx_devise_create_user.rb ... class DeviseCreateUsers < ActiveRecord::Migration[6.1] def change create_table :users do |t| ... ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ... end ... add_index :users, :reset_password_token, unique: true ... end end
2. Gmailのアプリパスワードを発行
下記記事を参考にしてアプリパスワードを発行します。
[*Rails*] deviseの使い方(rails6版) - Qiita
発行したアプリパスワードを後述するdotenv gemで使用する.env
ファイルに追加します。
3. dotenv gemを使用してメールアドレスとアプリパスワードを環境変数化
メールサーバの送信設定に使用する環境変数をdotenv gemで読み込む.env
ファイルに追加します。
dotenv gemの使い方 - karlley's tech blog
# .env GOOGLE_MAIL_ADDRESS = '使用するGmailのアドレス' GOOGLE_APP_PASSWORD = 'アプリパスワード'
4. メール送信用サーバをGmail用に設定
dotenv gemを使用して作成した環境変数でメールアドレスやパスワードでメール送信用サーバをGmail用に設定します。
メール送信機能はRailsで用意されているAction Mailerを使用します。
config/environments/development.rb
にGmail用にメール送信用サーバの設定を追加します。
初期状態ではdefault_url_options
のみ下記のようにデフォルトで設定されています。
# config/environments/development.rb require 'active_support/core_ext/integer/time' Rails.application.configure do ... # デフォルトで設定されている # Default url for mailer config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } end
ちなみに、devise gemセットアップ時にメール送信用サーバの設定を促されますがメール送信機能を使いたい時に設定すれば大丈夫です。
# devise gemセットアップに表示される $ rails generate devise:install ... =============================================================================== 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. * ... ===============================================================================
下記にようにGmailに合わせたAction Mailerの設定を追加します。
require 'active_support/core_ext/integer/time' Rails.application.configure do ... # Default url for mailer config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # メール送信失敗時のエラーを発生させる config.action_mailer.raise_delivery_errors = true # メール送信にSMTPを使用する config.action_mailer.delivery_method = :smtp # SMPTの詳細設定 config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, # HELOコマンドで使用するドメイン、たぶん無くてもok domain: 'smtp.gmail.com', # Gmailのメールアドレス user_name: ENV['GOOGLE_MAIL_ADDRESS'], # Googleのアプリパスワード password: ENV['GOOGLE_APP_PASSWORD'], # メールサーバーの認証の種類 authentication: 'plain', # STARTTLSを自動検出して有効化 enable_starttls_auto: true } end
ENV[]
はdotenv gemで設定した環境変数が展開されます。
Action Mailerの設定はRailsガイドと下記のリンクを参考にしました。
- メールサーバーの認証の種類:why is authentication: 'plain' the default setting for actionmailer in rails (with gmail smtp)? - Stack Overflow
- STARTTLS: STARTTLSとは - 意味をわかりやすく - IT用語辞典 e-Words
- HELOコマンド: ASCII.jp:メールを送る際に使われるSMTPの仕組みとは?
5. 送信元のメールアドレス設定
メールのfrom欄に表示される送信元のメールアドレスをconfig/initializes/devise.rb
に設定します。
ちなみに変更しなくても動作するのを確認したのでデフォルトのままでもokだと思います。
コードレビュー時に以下のアドバイスもらいました。
ここはdeviseが送信するメールのfromに当たる部分なので、
no-reply@example.com
のようなそれらしいアドレスにしておくと良いですね。
アドバイス通りにno-reply@example.com
に変更します。
# config/initializes/devise.rb Devise.setup do |config| ... # 変更前 config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' # 変更後 config.mailer_sender = 'no-reply@gmail.com'
以上でdeviseでメール認証を使ったパスワード再設定を実装は完了です。
/users/sign_in
にアクセスし、Forgot your password?
をクリックすると送信先のメールアドレスの入力を求められるので入力後、送信するとパスワード再設定用のメールが届くようになります。
追記
自前で用意したGmailを使ってメール送信の動作確認を行いましたがletter_opener_webというgemを使った方が実践的だということ教えてもらったので別記事にまとめました。
letter opener webでRailsのメール送信を確認する - karlley's tech blog
Gmailでの設定が面倒くさいという方はこちらを試してみると良いかもしれません。
まとめ
メール送信機能の公式ドキュメントが見つからず時間が掛かってしまいました。 メール送信機能はdeviseが用意してい機能ではなくRailsの機能だと理解していないことが原因でした。 gemの使い方にはまだまだ慣れが必要だと感じますが、少しずつ実装できているのでもっとたくさん触れて覚えていこうと思います。
参照
Railsにdeviseを使ってログイン機能を実装する - karlley's tech blog
[*Rails*] deviseの使い方(rails6版) - Qiita
dotenv gemの使い方 - karlley's tech blog
STARTTLSとは - 意味をわかりやすく - IT用語辞典 e-Words