Adding Magic Links to phx.gen.auth: a comprehensive guide
Creating a comprehensive magic link authentication solution for Phoenix
originally published
There's a few existing guides out there on doing magic links in Phoenix, in particular this great post by @JohnElmLabs . I wanted to extend John’s solution a little bit: I did not want any password handling code remaining.
This guide will make a couple assumptions. If they don't match what you want to do, you'll have to adjust some things accordingly. This guide assumes:
- You do not want to keep password auth around at all
- You want one flow for both logging in and signing up
Show me the code
Here’s a link to the an example commit showing what you need to do.
We can end up deleting:
- lib/example_web/live/user_confirmation_instructions_live.ex
- lib/example_web/live/user_confirmation_live.ex
- lib/example_web/live/user_forgot_password_live.ex
- lib/example_web/live/user_registration_live.ex
- lib/example_web/live/user_reset_password_live.ex
- associated tests
- and any context functions/other stuff that deals with passwords at all
So the files we’ll be keeping around for authentication are:
- lib/example_web/live/user_login_live.ex will handle login and registration now
- lib/example_web/live/user_settings_live.ex will handle email updates
And we’ll have some notable changes:
- I prefer /login over /users/log_in , and /account over /users/settings , so I’ve renamed them as such
- I’ve added my simple HTML email code from https://andrewian.dev/blog/phoenix-email-defaults/ (also available in video form )
- We’ll need a migration to remove hashed_password from the users table, and remove password and hashed_password from the schema
Since this example combines login and registration down to one system, new users get created in an unconfirmed state. You should probably have a mix task or an Oban job or something to remove old unconfirmed users.
Again, this post is just a quick summary. Refer to this commit for the code.
Git Patch
You can also download this commit as a Git patch . If you didn’t know, you can add .patch to the end of a commit url on GitHub and it will format it appropriately! 😎
# download as auth.patch
wget https://github.com/sevensidedmarble/phoenix-magic-links/commit/dd53d7979e1a094562c7b6a699b11b0ed5cc85e1.patch -O auth.patch
# you can then rename the modules
sed -i -e 's/Example/YourApp/g ; s/example/your_app/g' auth.patch
# and then apply with a 3-way diff
git apply -3 auth.patch
# or you can tell git to dump them into the working directory no matter what
git apply --reject auth.patch
You could probably tweak the generator to do just this set of things too, if you really wanted to.
Logging in on multiple devices
One of the biggest problems with magic link authentication, in my opinion, is the problem of ‘what do you do when someone opens the link on their phone’.
In this scenario, it is possible to present the user an interface where they can decide to log in on their phone or not. I’ll probably be adding these details in the future.