SendGridというメールサーバー(SMTPサーバー)を利用し、Herokuにデプロイしたアプリにメール認証機能を実装するまでの手順について書き残そうと思います。
開発環境
- Ruby 3.1.2
- Ruby on Rails 7.0.3
- Devise 4.8.1
- M1 Macbook Air 2020
- mac OS Monterey (ver. 12.4)
- ターミナル bash (Rosetta 2 使用)
Devise のインストールと各種設定を済ませておく
Deviseのインストールや設定方法についてはこちらの記事を参考にしました。
【Rails】 deviseの使い方とは?ログイン認証機能を実装しよう
以下、僕がDeviseをインストール、各種設定するまでの流れを書き残しておきます。
まずはGemfile
に下記のように記述します。
gem 'devise'
# ↓パスワードなどを環境変数するgem
gem 'dotenv-rails'
dotenv-rails
はメールアドレスやパスワードなど、gitに載せたくない情報を環境変数化するための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 *
===============================================================================
必要に応じて各項目の設定、追加等をしていきます。
1. 新規登録などで認証メールを送った際、メールの文中にある認証リンクのURLを設定
開発環境でメール認証を行う場合は、
config/environments/development.rb
内に下記のように記述します。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
また、本番環境でメール認証を行う場合は、
config/environments/production.rb
内に下記のように記述します。
config.action_mailer.default_url_options = { host: 'https://Herokuのアプリ名.herokuapp.com' }
2. ルートを設定する
deviseでは会員登録完了後などにルートに飛ぶ設定になっているため、
あらかじめconfig/routes.rb
にルートを設定しておく必要があります。
root "home#index"
3. フラッシュメッセージ用のタグをapplication.html.erb
に埋め込む。
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. deviseのカスタマイズ用のビューファイル作成
$ rails g devise:views
Deviseのビューをカスタマイズする時は、app/views/devise
以下のファイルを編集する。
Userモデルの作成
以下のコマンドを実行し、Userモデルを作成します。
$ rails g devise user
Deviseはデフォルトでは:username
カラムの設定がないため、必要であれば付け加えておきます。
メール認証を導入する場合は、マイグレーションファイルの## Confirmable
の部分をコメントアウトしておきます。
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :username
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 ←コメントアウトを解除する(メール認証用のカラム)
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
Userモデルに:confirmable
を追記します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
end
最後に、以下のコマンドを実行し、データベースを作成します。
$ rails db:migrate
このコマンドよく忘れるので注意!(自分への注意書きですw)
メール送信用サーバー(開発環境)の設定
config/environments/development.rb
に下記のように記述します。
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
# SendGrid の場合
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
}
こちらはSendGrid用の設定です。
Gmailを送信用サーバーにする場合は下記のように記述します。
# Gmail の場合
config.action_mailer.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => 'smtp.gmail.com',
:user_name => ENV['GMAIL_ADDRESS'],
:password => ENV['GMAIL_PASSWORD'],
:authentication => 'login'
}
Gmailのパスワードについては、2段階認証を設定している場合はアプリパスワードというものを取得し、それを入力する必要があります(2段階認証推奨)。
2 段階認証プロセスを有効にする | Googleアカウントヘルプ
アプリパスワードの取得方法はこちらの記事が参考になります。
パスワードやAPIキーなどgitにアップしたくない情報は.env
ファイルを作成し、環境変数化しておきます。
# Gmail
GMAIL_ADDRESS = "Gmailのメールアドレス"
GMAIL_PASSWORD = "Gmailのパスワード"
# 送信元のメールアドレス
SENDER_ADDRESS = "送信元のメールアドレス"
# SendGrid
SENDGRID_API_KEY = "SendGridのAPIキー"
ただ、このままだと$ git push
した時にコードがそのままアップされてしまうので、それを防ぐために.gitignore
ファイルに/.env
を追記します。
/public/assets
# Ignore master key for decrypting credentials and more.
/config/master.key
# ↓最下部に追記
/.env
開発環境用の設定はこれで完了です。
メール送信用サーバー(本番環境)の設定
本番環境の設定は、config/environments/production.rb
内に下記のように記述します。
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
}
ここで、:password
の設定はHerokuに環境変数として設定します。
設定方法は次の項目で説明します。
メールの差出人(送信元)情報の設定
送信元となるメールアドレスを入力します。
デフォルトでは “from@example.com” となっているので、ここに送信元にしたいメールアドレスを入力します。
app/mailers/application_mailer.rb
内には以下のように環境変数に設定したメールアドレスを記述します。
class ApplicationMailer < ActionMailer::Base
default from: ENV['SENDER_ADDRESS']
layout "mailer"
end
また、同じくdevise側の設定にも送信元メールアドレスを明記する必要があります。
Devise.setup do |config|
・・・
# config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
# ↓以下のように変更
config.mailer_sender = ENV['SENDER_ADDRESS']
・・・
end
(アプリケーション側で設定した送信元メールアドレスは、SendGrid側でも登録・認証しておく必要があります。詳しくは後ほど)
また、本番環境でも環境変数の値が適用されるよう、Heroku側で環境変数の設定を行います。
HerokuのSettingタブ > Config Vars
へ進み、以下のように環境変数のキーと値を入力します。
SendGridのAPIキーはSendGridであらかじめ作成しておきます。
まずはSendGridにアクセスしてアカウント登録する必要があります。(アカウント登録についてはこちら)
また、送信元メールアドレスについても、Heroku側だけでなくSendGrid側でもあらかじめ登録しておく必要があります。(詳しくはこちら)
Deviseを日本語化する
config/application.rb
に下記のコードを記述。
config.i18n.default_locale = :ja
ついでにタイムゾーンも "Tokyo"
に設定しておきます(デフォルトではUSになっている)。
# 変更前
config.time_zone = "Central Time (US & Canada)"
# 変更後
config.time_zone = "Tokyo"
次にconfig/locales
内にdevise.ja.yml
およびja.yml
ファイルを作成します。
作成したファイルに翻訳データをコピーします。
devise.ja.yml
の翻訳ファイルはこちらから、ja.yml
の翻訳ファイルはこちらからそれぞれコピーさせていただきました。
(作成していただいた方には感謝です)
Heroku経由でSendGridを使おうとするとアカウント凍結される
「Heroku SendGrid」と検索すると、Heroku経由でSendGridにアカウント登録し、その後 APIキーを取得して、、
という記事が多く見られるが、ここ最近SendGridのセキュリティが一段と厳しくなったことに伴い、
Heroku経由でSendGridを使おうとすると一瞬でアカウント凍結される(可能性が高い)。
【重要】APIキー認証および二要素認証が必須に変更されます | SendGridサポートチーム
Heroku Add-onsのSendGridトラブルシューティング
実際に僕もHeroku経由でSendGridに登録しようとしてみたのですが、何回やっても接続拒否(アカウント凍結)されてしまいます。
アカウント凍結されたらサポートに問い合わせてアカウントを有効化してもらう必要があるのですが、
Heroku経由の問題についてはどうやら日本ではサポート対象外とのこと。
Heroku経由で作成したアカウントが凍結されました。どうすればよいですか? | SendGridサポートチーム
なので、米国のSendGrid社に直接問い合わせなければなりません(もちろん英語で)。
英語での問い合わせに関しては下記の記事がとても参考になります。
Heroku Add-onのSendGridにログインできないトラブル
ちなみに、僕はHeroku経由でSendGridに登録するのを諦め、下記の方法で進めたらうまく登録できました。
SendGrid はHeroku経由ではなく、公式ページで直接登録する
SendGridにアクセスし、「Start for free」ボタンからアカウント登録を進めます。
アカウント登録の手順については下記記事がとても参考になります。
Heroku で SENDGRID を使って メール送信できるようにする
メールの差出人(送信元)情報をSendGridに登録する
SendGridを利用する場合、メールの差出人情報(メールアドレス、名前、住所など)をあらかじめ登録しておく必要があります。
登録していない場合、メールの送信ができません。
差出人情報の登録は下記の公式ドキュメントがとても参考になるので、こちらを参考に進めてみてください。(画像付き、日本語説明でとてもわかりやすかった)
以上の手順を実行すれば本番環境(Heroku)でSendGridを使ったメール認証が問題なく行えるはずです。
コメント