Post

Generate authentication like Rails 8 will

In the need for authenticator

Rails comes with no default way to authenticate the user, like Laravel does in the PHP world.

For a long time, the Devise gem was the good-enough-way-to-go for Rails, but didn’t reach 100% of adoption, for longly reddit-debated reasons.

From DHH :

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

The closest authentication generator for Rails 7

The authentication-zero gem is the closest solution so far.

I used it. I found it very enjoyable, very few lines of code, very easy to customize, full test suite to ensure that all my customisations don’t generate any kind of regression. Finally, I added some custom turbo_stream on top of validation to ensure a top-notch user experience.

The tutorial here is a simplified version of my current use.

Prerequisites

For this tutorial you will need :

1
2
3
4
5
ruby -v  # 3.3.0
rails -v  # 7.1.3
bundle -v  # 2.4.10
node -v # 20.9.0
git --version # 2.34.1

Build a default Rails app

Create a new Rails app like this :

1
2
3
rails new myapp
cd myapp

So nothing fancy here, no –minimal option or whatsoever. Stick with default is sometimes the best way to ensure more integration and less bugs.

Add authentication-zero

So we follow now the official docs of the gem and add :

1
2
3
bundle add authentication-zero
bin/rails generate authentication

You now have routes, controllers, models, migrations, tests, etc.

Ensure the whole test suite pass

1
2
bin/rails test:all

If everything is green, you can go to the next step :)

Add letter_opener gem

You need to add a way to view the sent email on your local machine, in order to play with the confirmation email (for example).

In order to do so, add in the Gemfile :

1
2
# inside Gemfile
gem "letter_opener", group: :development

and run

1
bundle install

Then inside config/environments/development.rb add

1
2
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true

Play with the application

By default, there are no users in the development database.

A first option is to add this inside the seed.rb file,

1
2
User.create(email: "simple@user.com", password_digest: BCrypt::Password.create("Secret1*3*5*"), verified: true)

And run

1
bin/rails db:seed

And relaunch your local web server with

1
bin/rails server

Now you can connect with the user described inside the seed file.

But that was cheating, right ?

A second option is to play with the application, first go to the home page, then click on “sign up”, then fill with one easy-to-remember email and password combination.

Then go to localhost:3000/letter_opener, and click the validation link.

Great! You now have a new verified user (who said “customer”? Not yet ;) )

Take time to read code

Don’t be too shy here to investigate the source code. The beauty of this gem is that there are no tons of complicated functions to read. Trying to understand Devise or Rodauth is another story.

Start with routes.rb, then try to play with the application, and try to understand what each unit test does and why.

Now you have a full authentication system that you fully understand!

Conclusion

I guess this article will be deprecated, as soon as the Rails 8 authenticator will be on scene.

Waiting for this, we have a clean, elegant and customisable solution : the authentication-zero gem.

This post is licensed under CC BY 4.0 by the author.