【devise】メール認証のサインアップ・イン・アウト機能

# 機能概要
* SMTPサーバー
    * Gmail or Sendgridを使用
* 「devise」
    * 新規会員登録・退会
    * ログイン・ログアウト
    * パスワードリセット
    * ユーザー情報編集
    * バリデーション
    * 日本語化
* その他
    * ログインしていないときにログイン画面にリダイレクト






# 前提
* 筆者はRailsインストール完了画面から検証しました。
* インストールの手順は、私の記事ですが下記を参照。
  * [Dockerでrailsローカル開発環境構築](https://qiita.com/jung_issei/items/7999512f63863a5bddb5)
  * [Dockerでrails開発環境構築(リバースプロキシで複数アプリを構築)](https://qiita.com/jung_issei/items/838c2215edcbabc5ed8b)


# 手順
## SMTPサーバーを構築
ホスト名、ユーザー名、パスワード、ポート番号をメモに控えましょう。
SMTPサーバーは下記のサービスを使ってみると良いと思います。

* 【無料】[Gmail](https://accounts.google.com/SignUp)(gmailアドレスを使うことになります。)
* 【無料】[Sendgrid](https://app.sendgrid.com/guide/integrate/langs/smtp)(任意のドメイン使用可。こちらのリンクから登録がおすすめ。日本語サイトからだと審査等で使えるようになるまで時間がかかるようです)



## 「devise」等設定手順

「devise」をGemfileに追加

```Gemfile:Gemfile
gem 'devise'
```

「devise」インストールコマンド

```terminal
$ bundle install
$ rails g devise:install
```

デフォルトURLの設定＆SMTPサーバー情報設定。環境変数を使用。

```ruby:config/environments/development.rb
  config.action_mailer.default_url_options = { host: ENV['WEB_HOST'], protocol: ENV['WEB_PROTOCOL']}
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => ENV['SMTP_ADDRESS'],
    :domain => ENV['SMTP_DOMAIN'],
    :port => ENV['SMTP_PORT'],
    :user_name => ENV['SMTP_USER_NAME'],
    :password => ENV['SMTP_PASSWD'],
    :authentication => 'login',
    :enable_starttls_auto => true
  }

```

「devise」で送信されるメールアドレスの設定(下記一行をコメントアウト。使用メールアドレスを追記)

```ruby:config/initializers/devise.rb
  # config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
  config.mailer_sender = ENV['SMTP_USER_NAME']

```


「devise」で送信されるメールのBCCに管理者メールを追加

```terminal
$ rails g mailer MyMailer sendmail_confirm
```

```ruby:config/initializers/devise.rb
Devise.setup do |config|
  ...
  config.mailer = 'MyMailer'
  ...
end
```



```ruby:app/mailers/my_mailer.rb
class MyMailer < Devise::Mailer
  def reset_password_instructions(record, token, opts={})
    super(record, token, opts.merge(default_opts))
  end

  def reset_password_instructions(record, token, opts={})
    super(record, token, opts.merge(default_opts))
  end

  def unlock_instructions(record, token, opts={})
    super(record, token, opts.merge(default_opts))
  end

  def default_opts
    {
        bcc: Settings.mail[:bcc]
    }
  end
end
```

ルートURLの設定(アクション名、コントローラーは任意に設定しましょう。)

```terminal
$ rails g controller Home top
```

「root to: 'home#top'」を追記

```ruby:config/routes.rb
#　・・・

root to: 'home#top'

#　・・・
```

ログインしていないときにログイン画面にリダイレクトをかける

```ruby:app/controllers/application_controller.rb
before_action :authenticate_user!
```


フラッシュメッセージ＆ログアウトリンク設置(表示させたい箇所に配置)

```erb:app/views/layouts/application.html.erb
<% if notice %>
  <p><%= notice %></p>
<% end %>
<% if alert %>
  <p><%= alert %></p>
<% end %>
<% if user_signed_in? %>
  <p><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></p>
<% end %>
```


「devise」のviewを生成

```terminal
$ rails g devise:views
```
上記コマンドを実行すると、「app/views」ディレクトリにdeviseディレクトリが生成されます。


　
　



「devise」のオプション機能(モジュール)の追加します。
今回は「user」を「devise」に使用するモデルにします。
下記コマンドを実行すると、「config/routes.rb」に「devise_for :users」が追記されます。

```terminal
$ rails g devise user

ex)
$ rails g devise member
$ rails g devise admin
```



コメントアウトを外すと、使用したいオプション機能(モジュール)が使えるようになります。
今回は「メール認証」のモジュールを使用したいので、「Confirmable」の部分をコメントアウト。

```ruby:db/migrate/*****_devise_create_users.rb
     ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

#　▼　▼　▼　下記のようにコメントアウト

     ## Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable
```


DBに反映

```terminal
$ rails db:migrate
```

「:confirmable」を追加し、使用するモジュールの指定します。

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



「devise」の日本語化

```ruby:config/application.rb
...
module Src
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    config.i18n.default_locale = :ja#追加

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end
```

```gemfile:Gemfile
gem 'devise-i18n'
gem 'devise-i18n-views'
```

```terminal
$ bundle install
$ rails g devise:views:locale ja
```
再起動後、日本語化されていました。

　
　
　
メール本文の変更は、「app/views/devise/mailer/」ディレクトリの下記ファイルから変更が可能です。

* 新規会員登録確認メール(confirmation_instructions.html.erb)
* メールアドレス変更確認メール(email_changed.html.erb)
* パスワード変更確認メール(password_change.html.erb)
* パスワードリセット確認メール(reset_password_instructions.html.erb)
* アカウント凍結確認メール(unlock_instructions.html.erb)


# 後続作業
[【Rails】【Devise】twitter・Facebookログイン実装](https://qiita.com/jung_issei/items/f569b6e0ed75672c8c29)
メール認証に加えてソーシャルログイン機能を実装する手順です。

# 参考
【plataformatec/devise: Flexible authentication solution for Rails with Warden.】
https://github.com/plataformatec/devise
公式。手順も掲載されています。

【deviseの使い方を徹底解説！】
https://www.pikawaka.com/rails/devise
手順がとても参考になりました。

【Rails DEVISE ユーザー登録時に管理者側にもメールが送信されるようにする。 - Qiita】
https://qiita.com/dawn_628/items/f1e4da88cd337b50fb7f
送信メールのBCCにメールアドレスを追加するのに参考になりました。

【Deviseで送信されるメールにbccを設定する方法 - ITアドベンチャー】
http://shimotori.github.io/blog-it/2013/05/11/1-set-bcc-to-devise-mail/
送信メールのBCCにメールアドレスを追加するのに参考になりました。

【【Rails5】Devise-i18nで日本語化する | RemoNote】
https://remonote.jp/rails-devise-i18n-locale-ja
deviseの日本語化の参考になりました。

【[Rails][devise]認証メールのテンプレートをカスタマイズしたい | よりこログ】
http://yrfreelance.com/2019/01/13/rails-devise-mail-template/
送信メール本文の変更で参考になりました。