Andy from Webcrunch

Subscribe for email updates:

Portrait of Andy Leverenz
Andy Leverenz

August 8, 2024

Last updated August 9, 2024

Easy Magic Links with Ruby on Rails

If you want to enhance your user experience by ditching passwords in favor of magic links, you’ve come to the right place. In this tutorial, I walk through how to implement passwordless authentication using the devise-passwordless gem, and we’ll use letter_opener to preview our emails right in the browser. Let’s get started!

Why Passwordless Authentication?

Before we dive into the code, let’s talk about why passwordless authentication is gaining traction. Passwords can be cumbersome and often lead to poor user experiences. Users forget them, reuse them across sites, or choose weak passwords. We can streamline the login process using magic links, making it easier and more secure for our users.

The devise-passwordless gem provides a passwordless authentication strategy for Ruby on Rails
applications using Devise. This strategy involves sending users a "magic link" via email, which they can use to log in without needing a password. Here are the key features and steps to implement it:

Key Features

  • Passwordless Authentication: Users receive a magic link via email to register or sign in, eliminating the need for passwords
  • Stateless Tokens: The magic links are stateless, meaning no database changes are required
  • Customizable: You can choose your token encoding algorithm or write your own
  • Compatibility: It can be combined with traditional password authentication within the same model
  • Multiple User Types: Supports multiple user (resource) types

Prerequisites

To follow along, you’ll need:

  • A Ruby on Rails application set up with Devise. I’ll create one from scratch so you can follow along.
  • Basic knowledge of Rails and how to navigate your application.

If you don’t have a Rails app yet, you can quickly create one by running:

rails new devise_magic_links -c tailwind -j bun
cd devise_magic_links

And then, you can add Devise to your app.

Step 1: Adding Required Gems

First, let’s add the necessary gems to our Gemfile. Open it up and add the following lines:

gem 'devise', '~> 4.8'
gem 'devise-passwordless'
gem 'letter_opener', group: :development

After saving the file, run:

bundle install

Step 2: Install Devise

If you haven’t set up Devise, let’s do that now. Run the following commands:

rails generate devise:install
rails generate devise User
rails db:migrate

This will set up Devise and create a User model for us. You can use multiple models with Devise and Devise passwords.

Step 3: Install devise-passwordless

Next, we’ll install the devise-passwordless gem. Run this command:

rails generate devise:passwordless:install

This command will configure your application to use passwordless authentication.

Step 4: Configure Your User Model

Now, we need to modify our User model to enable passwordless authentication. Open app/models/user.rb and add the :magic_link_authenticatable module:

class User < ApplicationRecord
  devise :magic_link_authenticatable, :registerable, :recoverable, :rememberable, :validatable
end

This tells Devise to use magic links for authentication instead of traditional passwords.

Step 5: Set Up Mailer for Development

To preview our emails during development, we’ll use letter_opener. In your config/environments/development.rb, add the following configuration:

config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

This setup will allow you to see the emails in your browser instead of sending them to an email address.

Step 6: Add a home/landing page

For the sake of this demo, I’ll add a StaticController with an index action to the app. This just serves as a place to add links to sign-in and registration forms.

rails g controller static index

Step 6: Update Your Routes

Now, let’s modify our routes to use the passwordless sessions controller. Open config/routes.rb and update it as follows:

Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: 'devise/passwordless/sessions' }
  root "static#index"
end

This tells Rails to route session requests through the gem's passwordless sessions controller.

Step 7: Customize Devise Views

Next, we want to customize the Devise views to remove any password fields since we won’t be using passwords anymore. If you haven’t generated Devise views yet, do it now:

rails generate devise:views

Because we won’t be leveraging passwords, run the following in your terminal to remove them from the file that was just generated.

rm -rf app/views/devise/passwords
rm -f app/views/devise/mailer/password_change.html.erb
rm -f app/views/devise/mailer/reset_password_instructions.html.erb

Now, let’s edit the registration and session views to remove password references:

  • app/views/devise/registrations/new.html.erb
    • Delete fields :password and :password_confirmation
  • app/views/devise/registrations/edit.html.erb
    • Delete fields :password, :password_confirmation, :current_password
  • app/views/devise/sessions/new.html.erb
    • Delete field :password

Step 8: Test the Magic Link Authentication

It’s time to see everything in action! Start your Rails server:

bin/dev

Now, navigate to the registration page (usually at /users/sign_up) and sign up a new user. After that, head over to the login page (usually at /users/sign_in) and enter the email address you just registered.

Thanks to' letter_opener, ' you should receive a magic link in your browser. Click the link, and voilà! You’re logged in without needing a password 👏.

Wrapping up

Congratulations! You’ve successfully implemented passwordless authentication in your Ruby on Rails application using the devise-passwordless gem and previewed emails with letter_opener.

This setup not only enhances user experience but also improves security by reducing the reliance on passwords.

Customize the views and email templates to match your application’s branding. Need templates? Check out my other project, Rails UI.

Link this article
Est. reading time: 5 minutes
Stats: 182 views

Categories

Collection

Part of the Ruby on Rails collection

Products and courses