💌

【Rails7】gemの設定ミスで本番環境のパスワードリセットメールが届かなかった話

2024/08/16に公開

はじめに

本記事では、Rails7を使用して本番環境でパスワードリセットメールを送信する際に、環境変数が読み込まれずメールが届かないという問題の原因と解決策について触れます。
具体的には、gem 'dotenv'とgem 'dotenv-rails'の設定ミスによって生じた問題に焦点を当てます。
パスワードリセット機能やgmail設定の詳しい実装手順については下記に参考記事や公式ドキュメントを掲載するのでこちらでは割愛します。

少しでも参考になることがあれば幸いです。

環境

  • Docker使用
  • Rails 7.1.3.4
  • Ruby 3.2.3
  • renderでデプロイ

前提

  • RailsでSorceryのサブモジュールとAction Mailerを利用してパスワードリセット機能を実装済みであること。
  • ローカル環境ではgem 'letter_opener_web'を使ってメール受信の確認ができていること。
  • メールサーバーはGmail.comを使用

実装の流れ

手順の詳細な説明は割愛しますが、ミスが発生した箇所を理解しやすいように、全体の流れを簡単にまとめました。
詳しくは以下のリンクをご参照ください。
(※順番はドキュメントや記事と異なる場合があります)

1.Sorceryモジュールの導入

  • サブモジュールの導入

2.Mailerの導入

  • Action Mailerを使用して、メール送信の設定を行う

3.ルーティングとコントローラーの設定

  • reset_password 機能のためのルーティングの設定とコントローラーを作成

4.ビューの作成

  • パスワードリセットのためのビュー(リセット申請画面、パスワード再設定画面、リセット申請画面に飛ぶためのリンク設定)

5.メール内容の作成・設定

  • メール本文の内容やデザインを設定する

6. letter_opener_webの導入・設定

  • ローカル環境でのメール確認のために'letter_opener_web'を導入

7. dotenv-railsの導入・設定   ← 今回のエラーになった原因

  • 環境変数の管理を行うためにdotenv-railsを導入し設定
  • .envでパスワードを管理

実装参考

発生したエラーについて

上記の流れに沿ってパスワードリセット機能を実装し、http://localhost:3000/letter_openerでリセットメールの確認ができました。
しかし、その後デプロイをして本番環境でパスワードリセットの申請をしてもメールが届きませんでした。(Yahooメール宛)

【本番環境でパスワードリセットの申請をした時のrenderのログ】
Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted というエラーが発生しており、メールの送信に失敗しています。

E, [2024-08-15T17:11:53.080001 #120] ERROR -- : [64152da3-9973-4c90-93ad-337d68ead7c9]   
[64152da3-9973-4c90-93ad-337d68ead7c9] Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted. For more information, go to
~~~~~~~省略~~~~~~~~~~~~~~
  UserMailer#reset_password_email: processed outbound mail in 5.8ms
I, [2024-08-15T17:11:53.078938 #120]  INFO -- : Failed delivery of mail 66be36d770478_786ae046878@srv-cq392kaju9rs7399pam0-c8b846754-2wgb9.mail error_class=Net::SMTPAuthenticationError error_message="535-5.7.8 Username and Password not accepted. For more information, go to\n"

考えたこと①

エラー文を読み、Net::SMTPAuthenticationError が発生していることから、Gmail の SMTP サーバーに対する認証が失敗していることが原因だと考えました。
同じエラーに遭遇した記事1
同じエラーに遭遇した記事2
上記記事をまずは参考にしました。
しかし、GmailのSMTPの設定やアプリパスワードの取得や設定内容には不足点が見つけられませんでした。

考えたこと②

私はアプリのAPIキーやパスワードを.envに記載して管理しています。
次に環境変数の読み込みがうまく行っていないかもしれないと考えました。

.env
#パスワードリセット用
GMAIL_USERNAME=aaaa@gmail.com
GMAIL_PASSWORD=abcdefghijklmn #取得したアプリパスワード

実施したこと

  • 環境変数の読み込み確認
    Image from Gyazo

読み込みができていないことが分かります。

  • Gemの再インストール
    Gemfileを再度確認したときに自身がインストールしているものがgem 'dotenv'であった事に気付きました。
    Gemfileを修正し、再インストールをしました。
    Githubを見てgem 'dotenv'をインストールしていましたが、Railsプロジェクトではgem 'dotenv-rails'を使用することが一般的だそうです。
    両者の違いを理解できていなかったことがエラーの原因となりました。
dotenvとdotenv-railsの違い

dotenv: 本番環境で使う場合は、手動で環境変数を設定する必要があることが多い。Ruby以外でも使用できる。
dotenv-rails: 本番環境でも.envファイルを利用して環境変数を読み込むことができる。gemをインストールすれば自動的に読み込んでくれる。

Gemfile
 gem 'dotenv-rails'
  • config/application.rbにdotenvをロードするよう記載してデプロイ
    Githubのドキュメントや参考記事を読み、「require 'dotenv/load'」を明示的に記載。
    デプロイしたところ、先ほどのNet::SMTPAuthenticationErrorは消えて以下のエラーが出ました。
  Bundle complete! 26 Gemfile dependencies, 110 gems now installed.
Gems in the groups 'development' and 'test' were not installed.
Bundled gems are installed into `/opt/render/project/.gems`
2 installed gems you directly depend on are looking for funding.
  Run `bundle fund` for details
bin/rails aborted!
LoadError: cannot load such file -- dotenv/load (LoadError)

以前自身が書いた記事にもあるように、
gem 'dotenv'のREADMEにも以下の記載があるので環境変数を読み込みするためのコードは不要です。

Rails
Dotenv will automatically load when your Rails app boots. See Customizing Rails to change which files are loaded and when.

解決策

  • 上記で記載したrequire 'dotenv/load'を削除してデプロイする
    ローディングするためのコードを削除してデプロイしたところ、デプロイは成功してエラーは消えました。
    パスワードリセットのメールが無事に届き、記載されているURLからパスワードのリセットができました。

以下成功時のrenderのログです。今度はメールの送信作業が完了しています。(一部個人情報のため変更済み)

INFO -- : [4fecd4ba-70ca-4365-9fa9-d13ebeb2f4d3]   Parameters: {"authenticity_token"=>"[FILTERED]", "email"=>"aaaa@yahoo.co.jp", "commit"=>"送信"}
I, [2024-08-16T04:31:05.194315 #114]  INFO -- : [4fecd4ba-70ca-4365-9fa9-d13ebeb2f4d3]   Rendered layout layouts/mailer.html.erb (Duration: 0.4ms | Allocations: 262)
I, [2024-08-16T04:31:05.195288 #114]  INFO -- : [4fecd4ba-70ca-4365-9fa9-d13ebeb2f4d3]   Rendered layout layouts/mailer.text.erb (Duration: 0.3ms | Allocations: 200)
D, [2024-08-16T04:31:05.198465 #114] DEBUG -- : UserMailer#reset_password_email: processed outbound mail in 8.8ms
        I, [2024-08-16T04:31:07.494949 #114]  INFO -- : Delivered mail 11111111111@srv-cq392kaju9rs7399pam0-f6f44b9f4-bb9p5.mail (2296.4ms)
D, [2024-08-16T04:31:07.495005 #114] DEBUG -- : Date: Fri, 16 Aug 2024 04:31:05 +0000
From: from@example.com
To: aaaa@yahoo.co.jp
Message-ID: <aaaaaaaaaaaaad@srv-cq392kaju9rs7399pam0-f6f44b9f4-bb9p5.mail>
Subject: =?UTF-8?Q?=E3=83=91=E3=82=B9=E3=83=AF=E3=83=BC=E3=83=89=E3=83=AA=E3=82=BB=E3=83=83=E3=83=88=E3=81=AE=E3=81=8A=E7=9F=A5=E3=82=89=E3=81=9B?=

まとめ

今回のパスワードリセットのメールが届かなかった原因は、
gem 'dotenv-rails'を使っていなかったため、本番環境において.envの環境変数が読み込まれなかったことでした。

gemをdotenvからdotenv-railsに変更し、再度デプロイしたところ、問題が解決しました。
今回の経験を通して、Railsプロジェクトでは環境変数の取り扱いには、dotenv-railsを使用することが推奨されることを改めて確認できました。
本番環境のデプロイ時には、ログを読み環境変数の設定や読み込み、gemの確認に至るまでしておくことが大切です。

今回もご覧いただきありがとうございました。

参考

Discussion