【Rails初学者】Rails8、Deviseでパスワード再設定メールをGmailで送るまでの手順（自分用メモ）

# 【Rails 8 + Devise】パスワード再設定メールをGmailで送るまでの手順（初心者メモ）

こんにちは。
Rails学習中の初学者です。
今回は、Gmailを使ってDeviseの「パスワード再設定メール」機能を実装したので、つまずいた点も含めてまとめておきます。

---

## ✅ 開発環境

- Rails 8.0.2
- ruby 3.2.x
- devise 4.9.4
- dotenv-rails
- Gmail（アプリパスワード使用）

---

## やりたいこと

- ユーザーが「パスワードを忘れた」とき、Gmailで再設定リンクを送信
- Deviseの `recoverable` 機能を使う

---

## ①Deviseの`recoverable`を有効にする

### `app/models/user.rb`
```ruby
devise :database_authenticatable, :registerable,
       :recoverable, :validatable
```

## マイグレーション追加
```bash
rails g migration AddRecoverableToUsers reset_password_token:string:index reset_password_sent_at:datetime
rails db:migrate
```
## ②メール設定（Gmailを使ったSMTP設定）
### 1. `.env` ファイルを作成して認証情報を記載

まず、アプリのルートディレクトリに `.env` ファイルを作成し、次のように記載する

```env
MAILER_SENDER=your_email@gmail.com
MAILER_PASSWORD=your_generated_app_password
```
`MAILER_SENDER`：Gmailのメールアドレス（例：example@gmail.com）
`MAILER_PASSWORD`：Gmailで発行したアプリパスワード

![スクリーンショット 2025-05-26 20.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955570/102e08bd-d454-463c-8097-f17e04271983.png)

※この.envファイルはGit管理から除外しておく
`.gitignore`に以下を追加する
```bash
.env
```

### 2. `dotenv-rails`をインストールして`.env`を読み込む
```ruby
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]
```
`bundle install`する
```ruby
bundle install
```


------
### Gmailでアプリパスワードを発行する手順:point_up:

今回はGmailを利用してメールを送信します。
**Googleアカウントを持っていない場合は作成する。**
Gmailを使用する場合、通常のログインパスワードではメール送信ができないため、Googleアカウントで「アプリパスワード」を発行する必要がある。

----
#### アプリパスワードの設定手順
1.Google アカウントにログインしたら、以下のURLにアクセスする。
https://myaccount.google.com/

2.サイドバーから「セキュリティ」をクリック

3.下にスクロールして、「2段階認証プロセス」を確認
- 二段階認証が無効の場合、有効化（これが必須）

4.二段階認証を有効化後、「アプリパスワード」という項目が表示される
https://myaccount.google.com/apppasswords に直接アクセスも可能

5.表示された画面でアプリ名など入力
![スクリーンショット 2025-05-27 13.50.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955570/ae8aebe7-7aff-4566-becc-d8bc471839b0.png)
作成をクリックすると、以下のような16文字の英数字が表示される
![スクリーンショット 2025-05-27 14.03.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955570/3ec281ac-e092-4246-b390-341fbd103af9.png)
```
xxxx xxxx xxxx xxxx
```
このアプリパスワードを`.env`の`MAILER_PASSWORD=`にコピペする

### ③環境変数が読み込まれているか確認
```ruby
rails console
> ENV['MAILER_SENDER']
=> "your_email@gmail.com"
```
値が返ってこない場合は`.env`の場所や`dotenv-rails`の導入漏れなどを再確認

---

### ④`config/environments/development.rb`にSMTP設定を追加

SMTP経由でGmailからメールを送るには、以下のように`development.rb`を編集する

```ruby
# config/environments/development.rb

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :smtp

config.action_mailer.smtp_settings = {
  address:              'smtp.gmail.com',
  port:                 587,
  domain:               'gmail.com',
  user_name:            ENV['MAILER_SENDER'],
  password:             ENV['MAILER_PASSWORD'],
  authentication:       'plain',
  enable_starttls_auto: true
}

config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
```
### Deviseの設定ファイルにもメール送信元を指定する
```ruby
# config/initializers/devise.rb
config.mailer_sender = ENV['MAILER_SENDER']
```
### ⑤メールテンプレートを編集する（任意）
デフォルトでは英語の簡易メールが送られてしまう。
日本語＋装飾されたメールに変更することで、ユーザーの安心感が増すかなと思います。
```erb
<!-- app/views/devise/mailer/reset_password_instructions.html.erb -->

<p><%= @resource.email %> さん、こんにちは。</p>

<p>パスワードの再設定をご希望とのことで、下記のリンクから再設定をお願いします。</p>

<p>
  <%= link_to 'パスワードを再設定する', edit_password_url(@resource, reset_password_token: @token) %>
</p>

<p>※このリンクは一度きりの有効です。</p>
<p>ご自身での操作でない場合は、本メールを破棄してください。</p>

<p>本メールは自動送信です。ご返信いただいても対応いたしかねますので、ご了承ください。</p>

```

### ⑥動作確認する
以下の手順でメール送信が正常に行われるかを確認
1.サーバーを起動
```ruby
rails s
```
2.ブラウザで以下にアクセス
```
http://localhost:3000/users/password/new
```
3.登録済みのメールアドレスを入力し、「再設定用メールを送信」
4.Gmailに届いたメールを開き、リンクをクリック
5.パスワード再設定画面が表示されれば成功

### 自分がつまずいたポイント、対処法

| エラー・問題 | 原因 | 解決策 |
|--------------|------|--------|
| `reset_password_token` が存在しないエラー | `recoverable` 用のマイグレーションが抜けていた | マイグレーションでカラム追加＋ `rails db:migrate` |
| `.env` が読み込まれない | `dotenv-rails` を導入していない | `Gemfile` に追加して `bundle install` |
| メール送信されない（送信成功と出ても Gmail に届かない） | `delivery_method` が `:smtp` になっていない | `development.rb` で正しく設定 |
| Gmail 側でブロックされている | アプリパスワードが未設定／間違っている | 再度アプリパスワードを発行して `.env` を確認 |


## `reset_password_token`について補足する
パスワード再設定メールに含めるリンクには、必ず`reset_password_token`を含める必要がある。
```erb
<%= link_to 'パスワードを再設定する', edit_password_url(@resource, reset_password_token: @token) %>
```
この`@token`はDeviseが自動的に生成する一度きりのトークンで、再設定対象のユーザーを識別するために使われている。

#### トークンがないことで
- トークンを省略すると、再設定ページにアクセスできても誰のパスワードをリセットするか判断できずエラーになる
- Devise側で`reset_password_token`をパラメータとして必須にしているため、URLに含まれていないとルーティングエラーやトークン不正エラーになる
#### トークンが生成されるタイミング
- ユーザーが`/users/password/new`からメール送信をリクエストすると、内部的に`set_reset_password_token`が呼ばれてトークンが生成される
- このトークンは`users.reset_password_token`カラムに保存され、リンクからアクセスされたときに照合される

## まとめ
Deviseのパスワードリセット機能をしっかり構築させようと思ったのですが、難しく感じました。
実際には環境構築やメール設定でつまずくポイントが多いなと思います。

- `recoverable` モジュールの有効化とマイグレーションを忘れない
- Gmailは**通常パスワードでは送信不可**。アプリパスワードを発行する
- `.env` ファイルと `dotenv-rails` を使ってセキュアに認証情報を管理
-  `reset_password_token`をパスワード再設定メールのリンクに含める

---

## 参考

- [Devise GitHub（公式ドキュメント）](https://github.com/heartcombo/devise)
- [Gmail アプリパスワードの設定](https://myaccount.google.com/apppasswords)
- [dotenv-rails（GitHub）](https://github.com/bkeepers/dotenv)


初学者のため、間違えていたらすいません。