Just do IT

思うは招く

devise でメール認証を実装したい【Rails】

やりたいこと

devise gemを使って、「登録 → 確認のメールがくる → メール内のリンクをクリック → 認証OK」の流れを作りたい。

前提

以下のようにdeviseのサンプルアプリを作成した。

rails new devise-email-auth
rails g devise:install
rails g devise:views
rails g devise User
rails g controller home index
  • deviseの機能を持ったUserモデルを作成
  • indexアクションを持つHomeコントローラーを作成
    • routes.rbにはroot "home#index"
  • ApplicationControllerにはbefore_action :authenticate_user!を追記
  • あえてまだrails db:migrateはしていない

その他deviseの初期設定に関して知識があやふやな場合は以下の記事が参考になるかもです。

k-koh.hatenablog.com

手順

これからメール認証を実装する。といっても、deviseの機能を使えばすぐに実装できる。

マイグレーションファイルでConfirmableの部分をすべてコメントアウトし、メール認証を有効にする。その後rails db:migrateを実行。

メール認証を有効にする

class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      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

もし途中からメール認証を実装したいなら

別にマイグレーションファイルを作成し、必要なカラムを追加する。

class AddConfirmableToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :confirmation_token, :string
    add_column :users, :confirmed_at, :datetime
    add_column :users, :confirmation_sent_at, :datetime
    add_column :users, :unconfirmed_email, :string
  end
end

deviseオプションを追加

Userモデルのdeviseオプションに:confirmableを追加。

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  #:lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable
end

メール設定

config/environments/development.rb にメールを送る側の設定をする。今回はサンプルアプリなのでgmailを使う。

  config.action_mailer.smtp_settings = {
    enable_starttls_auto => true,
    address => "smtp.gmail.com",
    port => 587,
    domain => 'smtp.gmail.com',
    user_name => "xxx@gmail.com", #gmailアドレス
    password => "xxxx", #gmailパスワード
    authentication => 'login'
  }

※間違ってもこのコードをGitHubに上げないこと!

gmailを使うとセキュリティに引っかかるはず。そのため、今回は特別に「安全性の低いアプリの許可」を有効にする。

https://myaccount.google.com/lesssecureapps

f:id:K_Koh:20200922162239j:plain

登録

サーバーを立ち上げ、登録画面で必要事項を入力する。

f:id:K_Koh:20200922163601j:plain

するとメールがくる。

f:id:K_Koh:20200922163651j:plain

これを認証すると、、

f:id:K_Koh:20200922163716j:plain

ログインできた。

注意

試し終わったら、「安全性の低いアプリの許可」を無効に戻しておく。

f:id:K_Koh:20200922163741j:plain

参考