LoginSignup
7
6

More than 5 years have passed since last update.

deviseにおける過去利用のパスワード制限

Posted at

はじめに

Railsのログイン機構のためのgemとして、deviseを利用している場合も多いですが、今回はセキュリティ要件として、過去に利用したパスワードを設定することができないようにするために、devise_security_extensionを利用して過去に設定したパスワードに対しての制限を行いました。

deviseの設定

まずは簡単にRailsアプリケーションの作成からdeviseの設定を行います。

アプリケーションの作成

$ rails new devise_app
$ cd devise_app/

deviseのインストール

Gemfileに以下を追記します。また今回はパスワード再設定のために、再設定メールをブラウザから確認できるようにletter_openerのgemもインストールします。

Gemfile
gem 'devise'
gem 'letter_opener'

つづいてbundle installの実行を行います。

$ bundle install

devise の設定


$ rails g devise:install

Running via Spring preloader in process 34286
      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

===============================================================================

deviseに対しての設定情報が表示されるので、表示を参考に必要な設定を行います。
まずconfig/environments/development.rbに以下を追記。

config/environments/development.rb
Rails.application.configure do

  # 追記
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.delivery_method = :letter_opener

end

次にuserでdevise 用のモデルを作成して、migrate処理を行います。



$ rails generate devise user

Running via Spring preloader in process 34446
      invoke  active_record
      create    db/migrate/20180422061404_devise_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      insert    app/models/user.rb
       route  devise_for :users

$ bundle exec rails db:migrate

== 20180422061404 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0025s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0007s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0010s
== 20180422061404 DeviseCreateUsers: migrated (0.0043s) =======================

以上からrailsサーバを立ち上げuser/sign_inでログインフォームの画面が表示されればOKです。

スクリーンショット 2018-04-22 15.27.47.png

devise_security_extension

devise_security_extensionとは

devise_security_extensionはdeviseに対してエンタープライズのセキュリティ要件として必要になる拡張機能を提供します。
今回、題材にした過去利用のパスワードの設定制限の他にも、パスワードのexpire機能やcaptcha機能などが利用できるようになります。

devise_security_extensionの利用

今回は過去のパスワード制限をするための設定を行なっていきます。
なおGithubのissueに記載があるように、Rails5.1以上の環境はgem指定のみであるとエラーになってしまうため、以下をのようにGemfileに追記します。

Gemfile
gem 'devise_security_extension', git: 'https://github.com/phatworx/devise_security_extension.git'

Gemfileへの追記を行なったらbundle,generatorとコマンドを実行します。

$ bundle install

$ rails generate devise_security_extension:install
Running via Spring preloader in process 34754
      create  config/initializers/devise_security_extension.rb
      create  config/locales/devise.security_extension.en.yml
      create  config/locales/devise.security_extension.de.yml
      create  config/locales/devise.security_extension.it.yml

devise_security_extensionにはdeviseに関しての様々な拡張機能が用意されていますが、今回は過去のパスワードの利用を禁止するためにpassword_archivableの機能のみを利用。

generatorによって取り込んだconfig/initializers/devise_security_extension.rbファイルからpassword_archivableに関しての設定のコメントアウトを外します。これによって過去に使用したパスワードのうち5回分(+現在のパスワード)のパスワードの設定を禁止することができます。
用途によってpassword_archiving_countの回数を変更すると良いでしょう。

config/initializers/devise_security_extension.rb

Devise.setup do |config|

  # How many passwords to keep in archive
  config.password_archiving_count = 5

  # Deny old password (true, false, count)
  config.deny_old_passwords = true

end

次にパスワードの履歴を保存するためのマイグレーションファイルの作成を行います。
マイグレーションファイルには公式のREADMEに従って定義を行えばOKです。

$ rails g migration create_old_passwords
Running via Spring preloader in process 34823
      invoke  active_record
      create    db/migrate/20180422065429_create_old_passwords.rb
db/migrate/20180422065429_create_old_passwords.rb
class CreateOldPasswords < ActiveRecord::Migration[5.2]
  def change
    create_table :old_passwords do |t| 
      t.string :encrypted_password, :null => false
      t.string :password_archivable_type, :null => false
      t.integer :password_archivable_id, :null => false
      t.datetime :created_at
    end 
    add_index :old_passwords, [:password_archivable_type, :password_archivable_id], :name => :index_password_archivable
  end 
end

マイグレーションファイルを作成したらDBに対して適用を行う。

$ bundle exec rails db:migrate

== 20180422065429 CreateOldPasswords: migrating ===============================
-- create_table(:old_passwords)
   -> 0.0024s
-- add_index(:old_passwords, [:password_archivable_type, :password_archivable_id], {:name=>:index_password_archivable})
   -> 0.0006s
== 20180422065429 CreateOldPasswords: migrated (0.0033s) ======================

最後にapp/model/user.rbテーブルに対して:password_archivableの設定を行います。

app/model/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable

  # :password_archivableを追記
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :password_archivable
end

これで設定は終了なので、サーバを再起動して確認。
過去5回に設定したことのあるパスワードを設定しようとすると、以下のようなエラーメッセージが表示されます。

スクリーンショット 2018-04-22 16.24.13.png

あとは日本語に対するlocaleファイルを作成すれば、日本語環境においても問題なく動作させることができます。

最後に

今回にdevise_security_extensionのgemを利用して、deviseに対して過去に設定したパスワードに対しての制限を行いました。
devise_security_extensionでは他にも、さまざな拡張機能をdeviseに対して設定できるので、機会があれば利用したいと思います。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6