Sending a one-time code via email fixes this, and is in practice about as easy to use as a link on desktop.
In our app (Loomio) we default to magic/codes, but let users use passwords if they prefer.
Sending a one-time code via email fixes this, and is in practice about as easy to use as a link on desktop.
In our app (Loomio) we default to magic/codes, but let users use passwords if they prefer.
It might be howling into the void but the conclusion I reach from this is that "Mobile email clients are a nightmare".
Generally speaking, embedded browsers in mobile apps are a terrible idea and break user expectations in multiple ways.
Meanwhile if the stupid app decides to hijack the link and use in-app browser, you can't do that. And IAB typically means you can't have app and browser in parallel and switch between them from app launcher, which would be sometimes useful. Slack does that, and it's annoying. But at least you can right click> copy URL and open it manually in preferred browser.
This is true, and as a user I want something better, but as a developer I need to build for what our users use.
I don't put "Site best viewed in Netscape Navigator", and I don't tell users they can only login on desktop.
I've no idea why it is so difficult for apps to open links in the user-selected browser. Isn't it just "xdg-open https://example.com/"?
In any case, I don't need to bother about whether any "cookie sharing" works or not if I only use one browser, do I?
It's not, it's a conscious decision to open links in chrome from gmail.
That is quite insane indeed.
And on top of that, Android keeps using Chrome as embedded browser. Even if you installed another one. MSHTML all over again.
[Note there are two things: 1) stupid apps putting a generic in-app browser inside the app - that's annoying; and 2) apps using a webview with a bridge between native app and a website, injecting some stuff and properly integrating the embedded website; something impossible to do by opening a website in regular browser]
No, theres implementation differences across API levels and the "shared cookie jar" implementation is newer and had some quirks. Its been a couple years since I was deep in this so it might have changed, but that was my experience back then.
The crux of it is, do you sign in the "originating" device (where the magic link was sent from), or the "consuming" device (where it was clicked).
Because it's veryyy common for people to be on a website on their computer, then click the link on their phone, but still want to be logged into their computer. We opted for the "originating" device. But this has security concerns.
(you also need to worry about multiple tabs on the same browser, but cookies make this easy to deal with)
But, what if an attacker just sends a link to loads of email addresses, and one of the receivers clicks on it by accident? Their account now has been taken-over.
So, this needs to be combined with the notion of "trusted devices", and of course, not breaking what the user expects. All in all, a TON of work to get some marginal gains in some sectors, mainly B2C. IMO, B2B should always have passwords as an option. 1Pass is too widely used to ignore.
The earliest Magic Links I remember using didn't have this problem, and this was before smartphones. The Link, back then at least, was only to authenticate that you can receive emails at a certain mailbox, not to authenticate whichever browser you used to open it. Your login attempt would keep the login (not logged-in) session open wherever you attempted to login from, while waiting for the Magic Link to be clicked on in the background. Whenever the Magic Link was clicked, irrespective of where it was clicked, your original browser session would stop waiting and log you in.
This also avoids the tedium of having to copy a link or code from one device/app to another. Just click, a browser tab/window opens for a short time, and then closes automatically after doing its job; you go back to wherever you attempted to log in, and simply proceed. This also simplifies post-login flows (like visiting a specific page you tried to access before being forced to login) in that such flows don't need to be tied to the Magic Link itself.
I can quickly access email on my phone - that doesn't necessarily mean I want to log in on my phone.
I think it’s just so much nicer of an experience to not have to worry where you go check the email or which browser opens when you click the link there.
The site you used to login was clearly where you intended to be, so that should definitely be one of the authenticated sessions when you click the link.
Switched to pin code entry, less fancy but achieves all the desired UX
A wrinkle in this complaint is that in most scenarios I don’t especially want a browser tab to be able to hold onto a persistent session while it’s closed due to privacy reasons, regardless of where that session state is held (and I realize there are a number of options).
This is a problem on low memory devices - the page gets forced to refresh because the system ran out of RAM. The iPhone 13 only has 4GB of RAM, and with many apps requiring 2+GB, it is frequent a web page can't stay loaded in the background.
Most android devices have 8GB plus RAM, so shouldn't hit that issue, although it still happens on very low end devices.
Edit: In fact, nevermind. My thinking on that was flawed. I think you’re right, that should be fine, as long as the DNS is encrypted.
If your user has one of those, then their account effectively has zero security since an attacker can attempt to log in, and the web security software will click the link, and the attacker (in the originating browser) is now logged in.
While I generally agree that this behavior is correct from a usability standpoint, it's not safe. That design allows a user to do a one-click account compromise when they receive a magic link that was sent in response to the login attempt of an attacker that happened to know the user's email address.
If the user clicks the magic link from the same device that they initiated the login from, it just opens straight into the app.
If the user clicks the magic link from a different device, it confirms the token and then the browser waiting on the original device logs in. It uses a generic browser/server messaging library to achieve this, based on whichever of HTTP SSE, WebSockets and polling is available.
If the user can't do either of these for whatever reason, such as email virus scanning or whatever, the bottom of the email also contains a code which can be entered onto the waiting login form, along with some information about never giving that code out to anyone else on the phone and checking the URL.
The magic link also has an interstitial page with an automatic POST form to deal with browsers and other things pre-opening links. There are also various points along the way that it attempts to check for phishing and perform additional interventions, such as if the magic link is clicked from a different country to the login request, or if the request is coming from a suspicious location, etc.
After all this is complete, it then does 2FA using SMS. The magic link login is only needed the first time you log in on a given browser as it saves a persistent cookie, but the SMS 2FA is needed every time. We don't support persistent sessions due to legal requirements.
We are also working on adding webauthn authentication, but early testing suggests most users find it very confusing. Mobile devices tend to handle it acceptably, but Windows' implementation in particular is currently very user hostile and often users worry they are being hacked. It also doesn't replace the email/SMS-OTP flow, because if the user is logging in from a new device, we still need a way to validate that it's them before they can subsequently authenticate with webauthn. We also support SAML SSO.
Most users are not interested whatsoever in carrying around a Yubikey. Even just using SMS-OTP got a lot of push back for being inconvenient. I think FIDO2 will work better for users when there's a good way of automatically synchronising their keys across all of their devices in a vendor-neutral.
For a lot of users the link didn't open in the app the way it was supposed to. Another surprisingly large subset of users had two phones, but the app wasn't on the phone they used for email. A one-time code definitely would have been better than a link.
From a security perspective as a user, it's no different than deferring to a social provider like Google, but has the benefit in that it gives a user more control over the third party they choose to delegate control to.
You allow username/password access and that's great too. I'm a fan of giving users options, but I don't know if anyone has done studies and found that a single login option actually is better for conversion. I'd be interested in seeing some numbers around that.
I wouldn't recommend a magic link for high value accounts, but I have pretty easy access to my mailbox, from everywhere (in contrast to my password manager, which is cumbersome to use from different accounts). I can also forward the email with the link to any device where I have email.
If it is a low-value account that I use infrequently, I'm a fan. The alternative is to just use 'forgot password' to get a link that resets my password. That is pretty much the same functionality.
I guess the hard part there is that no one building software thinks their app is 'low-value'. :)
The only real difference is if the password reset forces you to change the password and logs you out everywhere, then you can at least detect the break-in more quickly with the password approach.
I know the things I'm working on are low-value and appreciate it. In fact, I genuinely dread ever working on something high-value.
Email is the master key to most of your accounts.
I’ve been mulling over ideas for this in my head for a while, about fully standardizing the magic-link-to-login approach as a full single-sign-on implementation.
Sites could craft an email with a specific header scheme that denotes what it’s trying to do, for what website, and what the magic link key is. The body of the email would still look like a regular magic link email as it does today, as a graceful fallback behavior.
The website login screen could detect if the user agent supported magic links (best way to do this detection is TBD…), the requirements being be that (a) The OS has an email account configured for the user (like via Mail.app or similar), and (b) the OS can broker the security information of the magic links to the browser so that it doesn’t need “full” access to your email, just a standardized API for the browser to get the magic link header info.
If everything checks out, the UX for the login page would be:
- User: enters email address to log in with, hits submit
- Webpage: renders a quick loading spinner
- Website: Sends a magic link email to the email address
- OS: Sees the special magic link email and notices that the browser is in focus on the same origin (using an origin policy that requires the magic link’s headers matches the same origin as the page)
- Browser: Gets magic link/token from the OS
- Browser: Submits token to website
- User sees the login succeed.
- (Optional:) The mail client puts the email itself in a trash folder or some other place so the user doesn’t even notice it (although they should be able to dig it up if they want.)
The graceful fallback if the browser/OS setup is not supported would be that the website just renders the same “check your email for a link” page it would have normally sent.
Apple has enough integration to easily implement this on iOS and macOS, it would be great to see this happen. They already implement autofill for security codes sent to SMS or email, so they already have a similar level of integration, it just needs to be made seamless and not even require user input. It could also be a totally open standard so that any OS/desktop environment/etc could implement it.
Throw some structured data into the email. Email clients can detect and do the popup that hits a callback endpoint. Clients that don't support it still get the code via regular email.
I avoid the OS-layer implementation at the expense of the user having to confirm it's them, but this also means it works cross-device, which is what I'd want for 2fa anyway.
Seems like a lot of moving pieces that only an OS vendor (who controls both the browser and the email client and could build the integration between them) could implement.
That way, you can be signing in on a desktop browser, click the email link on your phone (or a different browser sandbox), and the desktop window will be signed in.
As others have pointed out, either login when the user has both generated and clicked on the magic link from the same IP (browser, where possible), or use magic codes (as opposed to links).
I don’t have a pw manager on my mobile device nor do I want one, getting a 35+ char into an input field on my phone is a PITA.
Do you have an example of the problems you've encountered? This is normally a turn-on-and-forget setting which is only slightly harder if you're using JavaScript to submit forms.
> I don’t have a pw manager on my mobile device nor do I want one, getting a 35+ char into an input field on my phone is a PITA.
What's your threat model for using long passwords but not using a password manager? I can understand why you might not want to store it on a cloud service even if it is encrypted but local storage is going to be more secure than entering it by hand if for no reason other than that it's harder to shoulder surf and harder to phish.
The only caveat for implementing is that you essentially need to have a mobile app for your site, while SMS/email auth are more universal.