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.
-
First, adjust your settings in
config/initializers/sorcery.rb
Make sure:magic_login
is listed inRails.application.config.sorcery.submodules =
and the additional relevant settings are specified, including the mailer class. -
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
- 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 %>
- 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
- 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
- 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