Haseeb Annadamban

Rails 8 Authentication Generator With User Registration

ยท 611 words ยท 3 minutes to read

Before Rails 8 we always used something like the devise gem for authentication. Even though Rails has all the features to build authentication, It was difficult to implement compared to devise gem. Rails 8 addresses this problem with an authentication generator. One good thing about this is that it is completely optional as a generator. You can still go with other authentication providers or build it yourself. The Rails 8 authentication generator includes login, logout, and password reset features. But interestingly it does not include a user registration feature. As per DHH, it is because “those are usually bespoke to each application”. But it is easy to implement. I have created a Rails app template for basic user registration generation. You can easily generate user registration using that.

Getting Started ๐Ÿ”—

The version of Rails 8 available now is in beta at the time of writing this. So, I will need one extra step for installation:

gem install rails -v 8.0.0.beta1
rails new rails8-auth

This will generate the default files. Now do an initial commit:

cd rails8-auth
git add .
git commit -m "default rails generated version"

Generating Authentication ๐Ÿ”—

We can use the auth generator now to generate basic authentication:

rails generate authentication

This will generate all the required files and make changes to some files.

  • The generated Authentication concern can be seen included in ApplicationController. It will make authentication required by default. The Authentication concern also adds an option to skip when authentication is not needed through allow_unauthenticated_access method. It also adds a helper method authenticated?. This itself handles the most difficult parts.
  • It generated the SessionsController for logging in and signing out. It also includes some security related code like rate limiting by default.
  • The PasswordsController includes the code to reset the password through email for the “Forgot Password” feature.
  • app/models/current.rb creates a Rails current attribute Current. The session is stored in it. So, any data in the session is accessible anywhere. This also makes the user available as Current.user from the session.

Now run the migrations after adding any other required fields:

rails db:migrate

Adding a Root Path Route ๐Ÿ”—

You can skip this if you already have root set in routes.rb.

Create a home page controller. The registration generator below needs it to be implemented.

rails generate controller home index  --skip-routes

Then set the root url at the end of the config/routes.rb

Rails.application.routes.draw do
  resource :session
  resources :passwords, param: :token
  get "up" => "rails/health#show", as: :rails_health_check
  # Rest of the routes
+  root "home#index"
end

Generating Basic User Registration ๐Ÿ”—

We will use the basic user registration template I have created in RailsBytes. You can find its source code at https://railsbytes.com/public/templates/Xg8sMD

Run the following command to generate a basic user registration. Here we allow anyone with an email to sign up for our application:

rails app:template LOCATION='https://railsbytes.com/script/Xg8sMD'

It will ask you if you need email confirmation. Press y if you want your users to confirm their email after signing up.

This will generate a RegistrationController and allow you to register users. If confirmation is selected it makes some minor updates in Authentication concern and adds a basic email confirmation feature.

Now run the migrations:

rails db:migrate

You can check the generated source code to learn more.

What’s next ๐Ÿ”—

  • This does not expire the confirmation token. You might want it to expire after a period of like 24 hours.
  • If you want to make some part of the codebase accessible without email confirmation. You can add an exception in Authentication concern.
  • You may want to store the unconfirmed emails in a separate field and copy it to email_address field after confirmation. But this will prevent login.

Wrapping up ๐Ÿ”—

That’s it.

Your Feedback Matters!

I'd love to hear your thoughts on this. Connect with me on LinkedIn Or Twitter