Passwordless authentication in phoenix – guide for implementing magic login links

TL;DR This guide assumes you are familiar with the basic flow, which you might have experienced in Slack or a growing number of apps: You provide an email address and get a magic link email containing a one time authentication token. Database quiz The token is valid for a short period of time, clicking the link redeems it and signs you in – no more passwords! The basic user model This guide assumes you already have a User model in place. Database url If that is not the case: Don’t worry and quickly generate it. Os x data recovery free For our purpose we just need an email property, extend it however you feel like … mix phoenix.gen.html User users email:string Even though the AuthToken is the main subject of this article it is pretty simple: All it needs is the token value, a timestamp of its creation and the relationship to a user. Fda 510 k database As there will be no user interface for anything token related, we can use the model generator to create it. Database research mix phoenix.gen.model AuthToken auth_tokens value:string user_id:references:users This uses Phoenix.Token to generate a signed 96 character long string everytime a token is created. Graph database This string is the token value and will be part of the magic link the user receives to sign in. Having prepared the AuthToken model we also need to wire up the other side of the association. Data recovery android free Let’s add the has_many relation to our User schema: schema “users” do # add the association among the rest of the schema Generate the controller using the HTML-generator and providing the –no-model flag: mix phoenix.gen.html Session sessions email:string –no-model The controller uses a separate TokenAuthentication service which we will cover in detail afterwards. Database software Let’s first take a closer look at the implementation of the actions described above: defmodule MyApp.SessionController do @moduledoc “” ” new is the only action that needs a template, but there is a little gotcha here: As we do not have a session model we cannot use the standard way of passing a changeset to the email form. Database software definition Instead we have to setup the form_for ourselves. Database error 7719 at exe This is what it looks like: < h2>Sign In < %= form_for @conn, session_path(@conn, :create), [ as: :session], fn f -> %> < div class= "form-group"> < %= label f, :email, class: " control- label" %> < %= text_input f, :email, class: " form- control", autofocus: true %> < %= error_tag f, :email %> < div class= "form-group"> < %= submit "Request login link", class: " btn btn- primary" %> < % end %> Signing Up Before we get to the TokenAuthentication service we shall not forget about the sign up process.

Data recovery nj A nice side effect of using passwordless authentication by providing the login link via email is that we will always have a verified email address. Iphone 6 data recovery mac You can utilize this to attach email verification to the login process for instance. When the user signs up we should provide the first login token along with the welcome email. Database design tool To do so we will use the TokenAuthentication.provide_token function that we also used before in the create action of the SessionController. H data recovery software alias MyApp.{TokenAuthentication, User} Now that we have already used the TokenAuthentication service extensively, let’s look at its implementation in detail. 1 care data recovery software I stored the module in web/services which you need to create as it is a custom folder for stuff like this. Database user interface It uses a mailer and AuthenticationEmail module which we will get to afterwards. Data recovery jaipur defmodule MyApp.TokenAuthentication do @moduledoc “” ” Sidenote: Almost all of the functions cover edge cases by pattern matching on the arguments. Database platforms You will see this pattern oftentimes in Elixir and it makes code much more readable: Instead of conditionally branching inside a single function you get a separate functions for every case. Data recovery group I just love this feature! 💜 The verify_token_value function ensures that the token has not expired. Database xls It does so by limiting the fetch from the database and setting a where clause for the time period. C database library You could also handle this by fetching the token without the clause and just using the Phoenix.Token.verify/4 function providing the max_age option. 510 k database This would give you the chance to have different error messages for cases of invalid and expired tokens. How to become a database administrator (I will leave that as an exercise for you – the :invalid and :expired cases should get handled in then) Once the token is used the verify_token function deletes the token. Database xml This way tokens cannot be redeemed multiple times. Database terminology This also implies that we might also want a task for cleaning up the database as unused tokens accumulate. Database theory We will save this task for a separate post though – let’s get to the mailer … Sending the emails We will use the Bamboo library for creating and sending email in our app. Database 1 to 1 relationship The official guide for sending email uses it too and the Bamboo documentation is great. Database testing It covers a wide range of topics as the library also has proper testing support and Phoenix integration. I assume you have the Bamboo basics set up and we can focus on the interesting parts. Database graph The Mailer module is just for actually sending the emails. Database naming conventions It just contains some wiring and is stored in lib/my_app/mailer.ex: defmodule MyApp.Mailer do @moduledoc “” ” The AuthenticationEmail module contains the function that prepares the email. Database entity It gets stored in web/emails/authentication_email.ex and this is what it looks like: defmodule MyApp.AuthenticationEmail do use Bamboo.Phoenix, view: MyApp.EmailView To keep it short let’s focus on what is absolutely necessarry in the login email. Database developer From an UX perspective this could use some more love, but you will get the idea: Here is your login link: As this article is already very long I did not include any tests – I might cover this in a separate article some time soon. Data recovery plan We also did not cover edge cases like the user losing access to the email address and recovering from that. Data recovery kansas city Things like that can get pretty app-specific, nevertheless I hope this guide gives you a basic understanding of how to approach passwordless authentication in Phoenix. The implementation might also serve as a foundation to add more authentication methods. N k database By encapsulating the authentication logic into a separate services instead of having it in the controller we can swap it out with a little bit of refactoring. Data recovery 2016 Updates The article got updated thanks to the feedback from reddit user q1t and bobbypriambodo in the Elixir Forum. 510 k database fda It now incorporates Phoenix.Token to sign and verify the token value. Database programmer Also we avoid leaking security information about users that exist in the app. Data recovery osx Thanks very miuch for the nice feedback!