Passwordless Authentication in Phoenix

I wrote a guide for implementing Passwordless Authentication a.k.a. “Magic Login Links”:

Feedback welcome!

17 Likes

Nice post!

A feedback (or more like a question): from a security point of view, would it be better not to let the user know whether or not the email is found on the DB? Just notify the user as if the email were successfully sent, but silently swallow the error on the server-side (you don’t actually send the email). That way any potential attacker wouldn’t be able to guess who’s registered on your system.

UX-wise it would pose a problem if the user mistype their email, but that can be circumvented by just printing back the email to the client (“We have sent a magic login link to foo@bar.com. See you soon!”).

But of course implementing it this way doesn’t mean you can left out the maximum number of tries validation (and possibly captchas) for preventing brute-force attacks and using your system as spam mail generator :slight_smile:

3 Likes

Thanks for the feedback! Good point, I’ll work that in!

Np, as a passwordless authentication fan, it’s great to see tutorials like this. Let’s strive to make passwords obsolete if we can help it :smile:

I don’t use passwordless authentication (yet!) but 99% of the time my errors are similar to this: “Wrong password / email combination” when one of the two are wrong. I try to keep them as simple as possible so no information are given to possible hackers who might try to brute force their way in.

fyi I updated the article incorporating your idea and mentioning this thread – thanks again! :slight_smile:

4 Likes

Thanks for the tutorial, I’m still trying to work out whether I want to use this in my app, for the following reasons:

  1. Is it easier for most people to check email to sign-in each time (or am I missing something)?

  2. Is it significantly more secure - to save user profiles etc, a user account still needs to be created and checked against for creating sessions between logins, which will always have some login info stored eg email address if not password?

  3. Is there a better way - eg as much as a developer may prefer not to use it, is signing in via Facebook etc the more practical version of passwordless authentication?

Perhaps, giving the user a choice to do one or the other or both would be best - log in by email link or password, whichever is most convenient at the time?

1 Like

I’d stick with either email link or regular login and password you can augment both with supporting whatever other options make sense for your situation e.g. FB, Twitter, GitHub

It is presumably easier than remembering passwords (needs more research though). What’s worse is that most people don’t know the existence of password managers, so you end up with reused passwords across sites. In essence, passwordless auth is just a revamped forgot-password feature :slight_smile:

Hmm, I don’t think I understand the question. But yes you need to provide email address for logging in (just as it is on @dennisreimann’s post). The security of saving user details on DB seems a different problem altogether :slight_smile:

Social logins are also a form of passwordless auth for your app. However I know a number of people that mind using their social account for signing into a service.

This is as far as I know what Slack does. They still accept passwords, but encourage the user (at least on mobile) to use the magic links.

I would like to remind you all that email is an unsafe medium. You’re not sending electronic letters, you’re sending electronic postcards.
When you send a ‘forgot password’ email, it can normally only be used to reset a password once. On top of that, the better services also time these links out after a few hours.

With magic links, people will get grumpy if you time their old link out, so all old links should continue working for a very long time.

But in both cases, I have the feeling that too much trust is put in the medium that is email. But solving this problem is a bit a chicken-and-egg problem, as techniques like PGP are somewhat of a hassle to set up and need a password themselves.

5 Likes

I think we might leave the actual intent of the article/guide: Of course there are considerations, trade-offs etc. involved, as its the case with any kind of authentication.

My goal was neither to propose passwordless authentication as the one-size fits all or best solution nor to give an overview of all available options and compare them. The guide is for people who decided that passwordless auth is a good fit for their case or that are considering it and would like to see what a potential implementation might look like. I hope it helps these people to decide whether or not it might be a good solution – maybe also as a supplement to other kinds of authentication.

There are lots of good resources out there for comparing the available options and a few of them are linked in the article. :slight_smile:

1 Like

I agree - you’ve said what has been at the back of my mind - that email isn’t typically securely transmitted, and relying on it for authenticating a web service, is just shifting the security problem from an app related server to an email server.

It is presumably easier than remembering passwords (needs more research though). What’s worse is that most people don’t know the existence of password managers, so you end up with reused passwords across sites. In essence, passwordless auth is just a revamped forgot-password feature :slight_smile:

I agree, more research is needed, but I wonder if it’s easier for someone to crack the password for a user’s email account than it is an app server? If not, does it really matter if a user uses the same password for several different apps?

At least they remember their commonly used/abused password, and if not, I often see people use built-in browser password saving services, if not a third party password manager, and on mobile eg iOS the auto-generated passwords that are saved to their iCloud keychain.

It would be interesting to see stat’s across sites/apps on the percentage of forgotten passwords, particularly immediately after sign-up. My guess is, that most people check their email, or do a password reset, or even sign up again if they aren’t yet ‘entrenched/invested’ in an existing user account.

There are many ways to look at the login problem from a time/age/memory curve across possible target demographics to others. An at the other end of the problem, where a login fail may be a a sign of a security issue, depending on the app - a trust based incentive for users to earn access eg email auth first, then password later - and anything in between, could be a solution.

I’m not sure if there’s a panacea for all sites/services/apps.

However, the main thing as a dev appeas to be to make sure:

  1. A signed up, non-first time user - can get access to their ‘super cool original username account’ (although many sites now allow any number of the same usernames based on a deeper ID) if they forgot their password or some part of their username after signup, and many are now moving to emails as the username as that’s easiest for users to remember, and thus reset their passwords to access their account and start using for the first time post-signup.

  2. Regular/‘frequently-enough’ users can reset their password easily, should it be forgotten, and when possible/if beneficial to the app, actually consider offering them a social login option for data/revenue sharing.

  3. There’s a policy in place for duplicate accounts from the same user eg whether it’s easy or not for an existing user to create a new account as a backup of sorts, or start a new one using the same email/phone no., should they have locked themselves out and not be invested/entrenched in their other user account. Email as passwordless auth can limit this, or an app can, as Facebook tends towards real names and phone numbers etc tied to them. The policy an chooses will depend on the growth/business model of the app, and perhaps ultimately dictate whether usernames/passwords are king or email is or not?

Hmm, I don’t think I understand the question. But yes you need to provide email address for logging in (just as it is on @dennisreimann’s post). The security of saving user details on DB seems a different problem altogether :slight_smile:

To rephrase my question - wouldn’t it be just as easy, if not easier, for a cracker to get a user’s email address from an app’s DB than a password, as emails are not often hashed like passwords? Sure, an email-based auth system may do that, but just as many big sites/apps continue to get in the news for plain text password storage, I imagine many will be caught out doing the same with email addresses for passwordless auth using email.

Social logins are also a form of passwordless auth for your app. However I know a number of people that mind using their social account for signing into a service.

I agree - I prefer not to use social logins for apps, and I think many developers that aspire to creating the ‘next big thing’ want to do so in a way that is attractive enough to encourage users to create a new account for their app. But sites like Facebook could easily swallow most of the web, apps, and any service in-between if there weren’t possible monopoly legal issues, simply because they are so popular, which means eventually not logging in via Facebook etc will be only for outliers. Personally, I’d prefer to put my trust in TouchID or something like it, but that’s a long way from being as mainstream as a social login, at least until Facebook does it (do they, I haven’t checked lately).

This is as far as I know what Slack does. They still accept passwords, but encourage the user (at least on mobile) to use the magic links.

That’s good, because in marketing terms, the price of something was traditionally the ‘entry point’, and there should be as many to cater to the spectrum of the demographic your business/service is targeting, and in the age of free social media/services/apps, there’s the need for as many entry points as possible - passwords, email, social logins, etc.

As an aside, this is a problem that I’ve been thinking about for sometime, and one that I think I’ve solved enough for enough uses cases to generalise beyond logins, and forms the foundation of the app I recently asked for developer interest from this community. Done right, it does a lot of interesting things, and many I think we can’t yet imagine. I’ve been chatting privately with a few here about working together, and if this topic is of interest to you and you can show aptitude in work related to it, PM me.

Thanks for the article/how-to Dennis, it has been well timed for my app, and I my apologies if I appeared to dismiss it, but I think it’s worth debating the current interest in using email as a passwordless auth for sites/apps.

As you say, you provided links in your article, and there have been other posts here recently with passworldless authentication using email, so keeping in the spirit of discussing design to IDEs to everything developer related, I thought it would be good to examine auth strategies related to passwordless auth using email here. Perhaps I should have created an entirely different post, but the other day, an announcement about a great new open source Elixir/Phoenix app turned into a discussion about the screengrabbing tool used to generate the .gif of the app rather than a discussion of how cool the actual app is, so I thought this community could accept a digression from your initial post to discuss the actual topic at hand - the merits and strategies/applications for passwordless auth using email.

Personally, I think it’s dance around a future solution, if not a backwards step - if we are trying to find a universal solution to logins, but it’s a step in the right direction for some demographics who may not remember their password or frequently challenged when logging in.

That’s not to diminish the technical achievement of your how-to - as I’ve written, it was timely for me and no doubt many others. Thanks!

1 Like

Can someone weigh in on what some of the tradeoffs might be between creating a separate model for the auth_token and associating it with the user model like in the tutorial here, versus adding an auth_token field directly to the user model, similar to how this guide approaches it.

By doing it like the guide you linked it’s not possible to have multiple tokens associated to any single user. If users request multiple tokens before authenticating you need to store them separately otherwise you cannot handle proper timeouts for those separately.