Rails v8 new authentication generator

Hello, I’m Bala, a Ruby developer at Money Forward.

As part of our Advent Calendar blog series, here’s a post for December 10th.

Rails 8.0 is here, bringing many exciting new features! One of the highlights is the new authentication generator, which simplifies the process of adding authentication to Rails applications.

In this blog, I’ll explore this feature in detail, walk you through how to use the generator to add authentication to a Rails app and explain each generated code.

So, Let’s dive in

DHH(David Heinemeier Hansson) the creator of ruby on rails introduced a new authentication generator in railsv8 rails/rails#50446

We can teach Rails developers how to use the basic blocks by adding a basic authentication generator that essentially works as a scaffold, but for authentication.

The main purpose of this generator is only to quickly get started with simple authentication into your rails project. And is not to replace the popular gems on community like Devise.

Ok, then why don’t we just use devise or other gems and what is the need for this authentication generator?

  • Well we can use devise, but it’s a very heavy and complex gem and have a lot of abstraction layers. So its not easy if you want to understand or if you want to override devise code according to your project needs.
  • For a new rails developer, who just wants to quick start with authentication, they may feel overwhelmed with the devise code and not feel comfortable with it.

As we all know rails follows the principle of ‘Convention over Configuration’ (let Rails do the hard work while you sip your coffee.)

Adding Authentication to a Rails App

First, create a new rails app running on v8.0.0. (If your rails version is not 8.0.0, update it with gem install rails -v 8.0.0)

rails new sample_auth_in_rails8

now its time to add authentication features to this app. execute the below command to add authentication to sample_auth_in_rails8 app.

bin/rails generate authentication

This will generate the essential files for basic authentication and including support for database-tracked sessions and also password reset functionality.

Here is the list of files generated.

Components generated by generator.

  • migration files
    • xxx_create_users.rb: creates the user table with email and password_digest columns. This migration file is also adding index on email column.
    • xxx_create_sessions.rb: create the session table to track the ip addresses and user agent of the active session.
  • models
    • user.rb: has has_secure_password helper to hash the password using bcrypt and store in password_digest column. This helper is available in bcrypt so you have bcrypt installed (In our case, rails automatically addes this to our gem file).
    • Session.rb: reference to user model.
    • current.rb: to handle request-specific global state of current user.
  • Authentication concern
    • This concern includes all the core methods of authentication, we will go through each one by one.
      • require_authentication: This is a before_action method that resumes the session if current session found on db. If not it rediects user to authenticate.
      • resume_session: find the session by cookie and updates the Current.session
      • request_authentication: This method saves request.url to session rediect user to authentication page.
      • authenticated? (helper method): return T/F whether user is having active session or not.
      • allow_unauthenticated_access: to bypass require_authentication callback
      • after_authentication_url: return url to redirect user after authentication
      • start_new_session_for: This method is to create a new session for current logged in user and updates the Current.session. (It also sets the cookie value to session id)
      • terminate_session: destroys the current session record and removes cookie value.
  • session controller
    • Session controller handles the user session management and it has the following methods:
      • new: render the html form for login for current user
      • create: handles the form submission and creates new session if input credentials are valid.
      • destroy: terminates the session and redirects to login page again.

password reset functionality

Along with the authentication logic, this generator also includes the password reset functionality on the user record. Let’s see the methods generated:

  • new: renders the password reset form to input email address.
  • create: handles the pasword reset form submission and uses PasswordsMailer to send password reset instructions to user.
  • edit: renders the edit password page where user can input the new password and ofcourse this action has before_action: set_user_by_token which is trying to find the user record based on the given token.
  • update: updates the user password and this method is protected by before_action.

Enhancements to has_secure_password

  • Rails 8 extends has_secure_password with new password reset capabilities. Two key methods have been added:

Here’s a practical example:

class User < ApplicationRecord
  has_secure_password
end

user = User.create!(name: "david", password: "123", password_confirmation: "123")
token = user.password_reset_token
User.find_by_password_reset_token(token) # returns user

# 16 minutes later...
User.find_by_password_reset_token(token) # returns nil

# raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
User.find_by_password_reset_token!(token)

Current limitations

  • No registration code is generated atleast as now(maybe in future versions of rails we expect to see)
  • The current generator only restricted to password based authentication.

conclusion

Rails 8 makes it easy to add authentication to your app with its built-in generator. It provides features like password-based login and password reset, saving you time and effort. (especially if you are new to rails and wants to add authentication with less effort)

While it doesn’t yet support user registration, future updates may bring more features. This tool helps you focus on building your app without worrying too much about authentication.

Keep an eye on Rails updates for new improvements!

bye-bye

ref:

Published-date