devise의 과거 사용 암호 제한

소개



Rails 로그인 메커니즘을위한 gem으로 devise 을 이용하여 과거에 설정한 비밀번호에 대한 제한을 했습니다.

devise 설정



먼저 Rails 애플리케이션을 작성하여 devise를 설정합니다.

애플리케이션 만들기


$ rails new devise_app
$ cd devise_app/

devise 설치



Gemfile에 다음을 추가합니다. 또한 이번에는 비밀번호 재설정을 위해 브라우저에서 재구성 메일을 확인할 수 있도록 devise_security_extension의 gem도 설치합니다.

Gemfile
gem 'devise'
gem 'letter_opener'

계속해서 letter_opener 를 실행합니다.
$ 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에 대한 설정 정보가 표시되므로, 표시를 참고로 필요한 설정을 실시합니다.
우선 bundle install 에 이하를 추기.

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

그런 다음 config/environments/development.rb에서 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 로 로그인 폼의 화면이 표시되면 OK입니다.

user/sign_in

devise_security_extension



devise_security_extension이란?



은 devise에 엔터프라이즈 보안 요구 사항으로 필요한 확장 기능을 제공합니다.
이번, 소재로 한 과거 이용의 패스워드의 설정 제한 외에, 패스워드의 expire 기능이나 captcha 기능등을 이용할 수 있게 됩니다.

devise_security_extension 사용



이번은 과거의 패스워드 제한을 하기 위한 설정을 실시해 갑니다.
또한 Github의 devise_security_extension 에 기재된 바와 같이 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

그런 다음 암호 기록을 저장하기 위한 마이그레이션 파일을 작성합니다.
마이그레이션 파일에는 issue에 따라 정의하면 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번에 설정한 암호를 설정하려고 하면 다음과 유사한 오류 메시지가 표시됩니다.

공식 README

그리고는 일본어에 대한 locale 파일을 작성하면, 일본어 환경에서도 문제 없게 동작시킬 수 있습니다.

마지막으로



이번에 devise_security_extension의 gem을 이용해, devise에 대해 과거에 설정한 패스워드에 대한 제한을 실시했습니다.devise_security_extension 그럼 그 밖에도, 다양한 확장 기능을 devise에 대해서 설정할 수 있으므로, 기회가 있으면 이용하고 싶습니다.

좋은 웹페이지 즐겨찾기