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 inApplicationController
. It will make authentication required by default. TheAuthentication
concern also adds an option to skip when authentication is not needed throughallow_unauthenticated_access
method. It also adds a helper methodauthenticated?
. 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 attributeCurrent
. The session is stored in it. So, any data in the session is accessible anywhere. This also makes the user available asCurrent.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.