Tìm hiểu về Gem Devise Security Extension

Như chúng ta đã biết, Devise là một gem hết sức quen thuộc và phổ biến trong các ứng dụng Rails. Gem Devise được sử trong quá trình xác thực người dùng, nó hỗ trợ hầu hết tất cả mọi việc bạn cần trong việc quản lí và xác thực người dùng trong hệ thống của bạn, chúng ta chỉ đơn giản là gọi ra và dùng nó thôi =))

Gem devise mặc định sẽ cung cấp cho người dùng 10 module chính, tuy nhiên đôi khi trong dự án của có những yêu cầu mới nằm ngoài những module mặc định này, lúc này chúng ta sẽ nghĩ đến phương án là override Devise. Việc này sẽ tương đối vất vả và đòi hỏi chúng ta phải đào sâu vào đọc source code của Devise, nhiệm vụ không hề dễ dàng phải không ạ. Nhưng thật may mắn chúng ta đã có những Gem "ăn theo" Devise 😃) sẽ cung cấp thêm các module mở rộng khác. Hôm nay, mình sẽ giới thiệu về Gem Devise Security Extension với 7 module mở rộng, và biết đâu được 1 trong các module naỳ đang là điều các bạn tìm kiếm để mang vào ứng dụng Rails của mình thì sao :3

Gem Devise Security Extension

Không lòng vòng, mình sẽ đi luôn vào giới thiệu 7 module mà gem này mang lại:

  • :password expirable - mật khẩu sẽ hết hiệu lực sau 1 thời gian (và cần update lại). Bạn có thể sẽ muốn sử dụng module này cùng với :password archivable để ngăn chặn các mật khẩu đã hết hạn hiện tại được tái sử dụng ngay lập tức như 1 mật khẩu mới
  • :secure validatable - 1 cách tốt hơn để xác nhận 1 người dùng với password mạnh hợn. Lưu ý,m không sử dụng cùng lúc với module :validatable của Devise
  • :password archivalble - lưu lại mật khẩu được sử dụng trong 1 bảng old passwords để kiểm tra lịch sử (không thể sử dụng mật khẩu cũ)
  • :session limitable - đảm bảo rằng chỉ có 1 tài khoản được login trong cùng 1 thời điểm
  • :expirable - hết hạn 1 tài khoản người dùng sau 1 số ngày nhất định không hoạt động (mặc định là 90 ngày)
  • :security questionable - tạo ra câu hỏi bí mật với mã xác nhận capcha dự phòng, cái này khá phổ biến trong những ứng dụng yêu cầu bảo mật cao nhỉ 😄
  • :paranoid verification - admin có thể tạo ra mã xác minh rằng người dùng cần phải điển vào nếu không thì sẽ ngăn cản truy cập sử dụng ứng dụng

Ngoài 7 module trên chúng ta còn 1 tính năng bổ sung (cách setting sẽ khác 1 chút với 7 module trên) là

  • captcha support: cho việc signup, signin, recoverunlock tài khoản

Cách sử dụng

Hết sức đơn giản và implement tương tự các Gem khác, đàu tiên add vào Gemfile

gem 'devise_security_extension'

bundle install và chạy lệnh generator để sử dụng

rails generate devise_security_extension:install

Các thiết lập được thiết lập trong config/initializers/devise.rb, và sẽ để ở trạng thái comment Tùy xem chúng ta cần sử dụng 1 module nào để thiết lập enable lại các lệnh trong file trên:

Devise.setup do |config|
  # ==> Security Extension
  # Configure security extension for devise

  # Should the password expire (e.g 3.months)
  # config.expire_password_after = 3.months

  # Need 1 char of A-Z, a-z and 0-9
  # config.password_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/

  # Number of old passwords in archive
  # config.password_archiving_count = 5

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

  # captcha integration for recover form
  # config.captcha_for_recover = true

  # captcha integration for sign up form
  # config.captcha_for_sign_up = true

  # captcha integration for sign in form
  # config.captcha_for_sign_in = true

  # captcha integration for unlock form
  # config.captcha_for_unlock = true

  # security_question integration for recover form
  # this automatically enables captchas (captcha_for_recover, as fallback)
  # config.security_question_for_recover = false

  # security_question integration for unlock form
  # this automatically enables captchas (captcha_for_unlock, as fallback)
  # config.security_question_for_unlock = false

  # security_question integration for confirmation form
  # this automatically enables captchas (captcha_for_confirmation, as fallback)
  config.security_question_for_confirmation = false

  # ==> Configuration for :expirable
  # Time period for account expiry from last_activity_at
  config.expire_after = 90.days
end

Ví dụ ở đây mình chỉ sử dụng 2 module security questionexpirable

Chú ý: với module :secure validatable chúng ta cần add thêm gem 'rails_email_validator'

Implement module Session Limitable

Ứng với mỗi module thì chúng ta sẽ add thêm 1 vài column vào, chi tiết cụ thể schema các bạn có thể xem link github về Gem ở cuối bài, ở đây mình sẽ chỉ đi chi tiết vào việc dùng 1 module cụ thể nào đó (module_ Session Limitable_)

Đầu tiên chúng ta vẫn add vào Gemfile và bundle rồi chạy command generate như bình thường

gem 'devise_security_extension'

rails g devise_security_extension:install

Tiếp theo, chạy:

rails g migration AddSessionLimitableToUsers unique_session_id

Và, edit migration file như sau:

class AddSessionLimitableToUsers < ActiveRecord::Migration
  def change
    add_column :users, :unique_session_id, :string, limit: 20
  end
end

Chạy lại migrate

rake db:migrate

Cuối cùng sửa file app/models/user.rb như sau:

class User < ActiveRecord::Base
  devise :session_limitable # other devise options
  ... rest of file ...
end

DOne!!! Bây giờ bạn thử đăng nhập từ 1 trình duyệt khác thì bất cứ tài khoản nào đang đăng nhập sẽ bị log out ra. Tuy nhiên Gem này chỉ thông báo sao khi log out còn trước khi log in vào sẽ không có thông báo đâu 😦( cái này bạn sẽ phải custom lại =))

Tham khảo: https://github.com/phatworx/devise_security_extension