Securing Ruby on Rails Applications: Part 6 (Use Two-Factor Authentication (2FA))

In an increasingly digital world, ensuring the security of user accounts has become a critical concern for web developers. One effective method to safeguard user data and prevent unauthorized access is through Two-Factor Authentication (2FA). This authentication process adds an extra layer of security by requiring users to provide two forms of identification before accessing their accounts. In this article, we will explore how to implement 2FA in a Ruby on Rails application, with code examples to guide you through the process.

What is Two-Factor Authentication?

Two-Factor Authentication is a security mechanism that combines two independent factors for user verification. The factors typically fall into three categories: knowledge factors (e.g., passwords, PINs), possession factors (e.g., physical tokens, smartphones), and inherence factors (e.g., biometrics). By requiring users to provide two different types of credentials, 2FA significantly enhances the security of user accounts, even if one of the factors is compromised.

Implementing Two-Factor Authentication in Rails:

To implement 2FA in a Rails application, we will use the Devise gem, a flexible authentication solution for Ruby-based applications. Devise provides a solid foundation for user authentication, and we can build upon it to incorporate 2FA.

Step 1: Set up Devise:

First, we need to add Devise to our Rails project. Open your Gemfile and add the following line:

1
gem 'devise'

Run bundle install to install the gem, and then execute the Devise generator to set up the required files:

1
rails generate devise:install

This command generates an initializer file and other necessary configuration files.

Step 2: Generate the User Model:

Next, generate the User model with Devise using the following command:

1
rails generate devise User

This command generates the User model and sets up basic authentication routes.

Step 3: Add 2FA Functionality:

To add 2FA functionality, we will use the devise-two-factor gem. Add it to your Gemfile:

1
gem 'devise-two-factor'

Run bundle install to install the gem.

Step 4: Generate the 2FA Migration:

Generate a migration for the 2FA columns in the User model:

1
rails generate devise_two_factor User otp_secret_key:string encrypted_otp_secret_key:string encrypted_otp_secret_key_iv:string encrypted_otp_secret_key_salt:string otp_required_for_login:boolean otp_failed_attempts:integer otp_failed_attempts_count:integer

This migration adds columns to store the user’s secret key, encryption details, and related settings.

Step 5: Apply the Migration:

Run the migration to update the database:

1
rails db:migrate

Step 6: Enable Two-Factor Authentication in User Model:

Open the User model file (app/models/user.rb) and add the following lines:

1
devise :two_factor_authenticatable, :otp_secret_encryption_key => ENV['DEVISE_SECRET_KEY']

This configuration enables 2FA for the User model.

Step 7: Set up the Controller and Views:

To handle the 2FA setup and verification processes, we need to create a controller and views. Run the following generator command:

1
rails generate devise_two_factor:controllers users

This command generates the necessary controllers and views for 2FA.

Step 8: Configure the Routes:

In your config/routes.rb file, add the following line to override the default Devise routes:

1
2
3
4
5
6
7
8
9
10
devise_for :users, controllers: {
  sessions: 'users/s

essions',
  registrations: 'users/registrations',
  confirmations: 'users/confirmations',
  passwords: 'users/passwords',
  unlocks: 'users/unlocks',
  two_factors: 'users/two_factors'
}

Step 9: Secure Sensitive Routes:

To enforce 2FA for specific routes, you can use the before_action in your controllers. For example:

1
before_action :authenticate_user!, :authenticate_user_using_2fa

This code ensures that the user is authenticated and has completed 2FA before accessing the specified routes.

Conclusion:

Implementing Two-Factor Authentication (2FA) in your Rails application provides an additional layer of security, bolstering the protection of user accounts against unauthorized access. By following the steps outlined in this article, you can integrate 2FA seamlessly into your application using the Devise gem. Remember to stay vigilant and prioritize security measures to safeguard your users’ valuable data.