Magic Login Basic Setup - Sorcery/sorcery GitHub Wiki

Magic Login or Passwordless Authentication is fairly easy to do with the module built in to the Sorcery gem.

  1. First, adjust your settings in config/initializers/sorcery.rb Make sure :magic_login is listed in Rails.application.config.sorcery.submodules = and the additional relevant settings are specified, including the mailer class.

  2. Add to your routes file Route and controller names are only examples, use any names that work for your app:

  resources :magic_links, only: [:create]
  # this is for creating a new magic link and sending it to your user

  resources :magic_sessions, only: [:new]
  # this creates the new session when the user clicks on the generated link
  1. Create a form that allows users to request a magic login link email
<%= form_with url: magic_links_path, method: :post do |f| %> # this sends a post request to the controller below
  <%= f.label :email, 'Email address' %>
  <%= f.email_field :email, autocomplete: :email, required: true %>
  <%= f.submit "Send me the magic link!" %>
<% end %>
  1. In your controllers/magic_links_controller.rb
class MagicLinksController < ApplicationController
  skip_before_action :require_login, only: [:create]

  def create
    @user = User.find_by(email: params[:email]) 
    
    if @user
      @user.generate_magic_login_token! # this is required by your mailer in the next step

      LoginMailer.with(user: @user).magic_login_email.deliver_later #or deliver_now
      redirect_to root_path, notice: 'Magic link sent!'
    else
      redirect_to new_user_path #ask user to create account or whatever logic you want here
    end
  end
end
  1. Send an email with the magic token
class LoginMailer < ApplicationMailer
  def magic_login_email
    @user = params[:user]
    @url = new_magic_session_url(token: @user.magic_login_token)

    # this is where the "magic" happens lol
    # the new_magic_session_url controller is shown below
    # the token url param uses the token created in the previous step
    # use this @url in your mailer layout to link your user back to your app to login

    mail(to: @user.email, subject: 'Your Magic Login Link')
  end
end
  1. In your controllers/magic_sessions_controller.rb
class MagicSessionsController < ApplicationController
  skip_before_action :require_login, only: [:new]

  def new
    user = User.load_from_magic_login_token(params[:token]) #this should be present from your email sent in previous step
    if user
      auto_login(user)
      after_login!(user)
      user.clear_magic_login_token!
      redirect_to app_root_path, notice: 'Welcome!' 
    else
      redirect_to root_path, alert: 'Login link expired. Please enter your email address again.'
    end
  end
end
⚠️ **GitHub.com Fallback** ⚠️