Railsで一番有名なユーザ認証機能のGemがdeviseです。
Ruby on Rails チュートリアルではユーザの認証機能をスクラッチで開発しますが、deviseを使うとカンタンにユーザの認証機能を実装することができます。deviseを使ってユーザ認証機能を実装したときのメモです。

前提条件
1 2 3 | rails 5.0.0.1 devise 4.2.0 |
deviseのインストール
1. プロジェクトの作成
1 2 3 | $ rails _5.0.0.1_ new devise_app $ cd devise_app |
詳細はRailsでWEBアプリケーションを作成するときの備忘録より
2. Gemfileを編集してインストール
Gemfileにdevise
を追加
1 2 3 4 5 6 7 8 | source 'https://rubygems.org' ... gem 'devise' ... |
1 2 | $ bundle install |
deviseの初期設定
generateコマンドでdeviseをインストール
以下のようなメッセージが表示されるので、それどおりに設定していく
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | $ rails g devise:install Running via Spring preloader in process 50039 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 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. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 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> 4. You can copy Devise views (for customization) to your app by running: rails g devise:views =============================================================================== |
1. デフォルトURLの指定
config/environments/development.rb
に以下を記載
1 2 | config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } |
2. root_urlの指定
1番で指定したURLにアクセスした際に表示されるページを指定する
まだ、ページがないのでgenerate
コマンドで作成する
1 2 | $ rails g controller Home index |
config/routes.rb
を以下のように修正
1 2 3 4 | Rails.application.routes.draw do root 'home#index' end |
3. flashメッセージの設定
app/views/layouts/application.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!DOCTYPE html> <html> <head> <title>DeviseApp</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html> |
4. deviseのViewを生成
1 2 | $ rails g devise:views |
たくさんファイルが生成される
Userモデルの設定
登録情報を保存するためのモデルを作成していく
1. Userモデルを生成
モデルのgenerate
コマンドではなく、devise
のコマンドで生成する
1 2 | $ rails g devise User |
db/migrate/タイムスタンプ_devise_create_users.rb
に、以下のようなマイグレーションファイルが生成される
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class DeviseCreateUsers < ActiveRecord::Migration[5.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 |
1 2 3 4 5 6 7 | class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end |
デフォルトでは、
- Database authenticatable: パスワードを暗号化してDBに保存。認証はPOSTリクエスト or HTTP Basic認証
- Registerable: ユーザ自身がサインアップ・編集・削除することを許可
- Recoverable: パスワードをリセットして、それを通知
- Rememberable: Cookieでユーザのを記憶するトークンを生成・削除
- Trackable: サインイン回数・時間、IPアドレスを保存
- Validatable: Emailやパスワードのバリデーション
が、ONになっている
- Confirmable: メールで配信して、URLクリックしたら本登録
- Lockable: 一定回数サインインに失敗するとアカウントロック
- Timeoutable: 一定時間活動してないアカウントのセッションを破棄
- Omniauthable: TwitterやFacebookの認証を実装するために使用
をONにするには、以下の修正が必要
まず、UserModelを変更する
今回は、omniauthable以外全部実装してみる
1 2 3 4 5 6 7 8 | class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable end |
次に、マイグレーションファイルを変更する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class DeviseCreateUsers < ActiveRecord::Migration[5.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 |
最後に、マイグレーションコマンドを叩く
1 2 | $ rails db:migrate |
Viewの編集
app/views/layouts/application.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <!DOCTYPE html> <html> <head> <title>DeviseApp</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <header> <nav> <ul> <% if user_signed_in? %> <li> <%= link_to 'Edit', edit_user_registration_path %> </li> <li> <%= link_to 'Logout', destroy_user_session_path, method: :delete %> </li> <% else %> <li> <%= link_to 'Sign-up', new_user_registration_path %> </li> <li> <%= link_to 'Login', new_user_session_path %> </li> <% end %> </ul> </nav> </header> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html> |
Confirmable – アカウント登録確認メールを送信
1. confirmableとは?
新規登録入力後確認メールを送信して、届いたメールのURLがクリックされるとログイン可能になる仕組み
2. メールの設定
config/initializers/devise.rb
に、送信に使用するメールアドレスを設定する
1 2 3 4 5 6 7 8 9 10 | Devise.setup do |config| ... config.mailer_sender = '使用するメールアドレス' ... end |
config/environments/development.rb
にメールのsftp情報を入力する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ... # mail setting config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => "smtpサーバー名", :port => '587', :user_name => "アカウント名", :password => "パスワード", :authentication => :login, :enable_starttls_auto => true } end |
ここで注意!
もし設定を間違えていて、535 5.7.0 authentication failed.
というエラーが出たら、ソース修正後、Railsのサーバーを必ず再起動する
どうやら、再起動しないと設定ファイルが読み込まれない
3. 届いたメールを確認する
メールを正しく設定できると、サインアップ後に登録したメールアドレス宛に有効化リンクが付いたメールが届く
リンクをクリックすると、ユーザが有効化されてログインできるようになる
app/views/devise/confirmation_instructions.html.erb
にてメールの内容を変更できる
Lockable – アカウントをロック
Locableとは?
アカウント認証を一定回数以上間違えると、アカウントロックする機能
うーん、ブルートフォースとか防げるっちゃ防げるけど、
メールリストにヒットしたユーザのアカウントを全部ロックされちゃ困るわな
単純な、嫌がらせは防げるのかな?
ひとまず、実装してみまっしょ
設定方法
config/initializers/devise.rb
で以下のような記載をする
今回は、5回ログインに失敗したら、登録したメールアドレスにアンロックのURLを送信するような設定を
maximum_attempts
の数字は、失敗してもいい回数なので4に設定(つまり5回目でNG)
1 2 3 4 5 6 7 8 | ... config.unlock_strategy = :email config.maximum_attempts = 4 ... |
Timeoutable – 一定時間アクセスのないセッションを破棄
Timeoutableとは?
一定時間アクセスがないセッションをタイムアウトにする機能
設定方法
config/initializers/devise.rb
にて設定
config.timeout_in
に〇〇分後にタイムアウトする時間を設定
1 2 3 4 | ... config.timeout_in = 30.minutes ... |
アクセス制限をかける
ここまででだいたいサインアップ・サインインの機能を実装した
しかし、全ページにアクセスできてはせっかくの認証の意味がない
そこで、Home#index
にはログインしたユーザしかアクセスできないようにする
ログインしていないユーザがHome#index
つまりroot
の画面にアクセスした場合、ログイン画面に遷移するようにせっていする
ログインしていないユーザはログイン画面に強制リダイレクト
app/controllers/application_controller.rb
にbefore_action :authenticate_user!
を追記
各コントローラー毎にも設定できる
まとめ
Railsチュートリアルで結構たいへんなアカウント認証機能づくりですが、deviseを使うとカンタンに実装できました
deviseを利用するとソーシャルログイン機能も実装できる (TODO いつか実装してみる)
Devise + CanCanCan + rolify
を組み合わせることで、ユーザの権限も管理できる (TODO いつか実装してみる)
もしよければ応援クリックお願いします
↓↓↓↓↓
