I'm intested in building some kind of password-less login between a mobile app and an API (assuming I can control both). The motivation is that having to login is very annoying for users and has security risks (eg. users will reuse existing passwords) and I want the users to be able to get started with the app immediately.
I'm wondering if there are some techniques that could work. For instance:
- Generate and random login/password on the mobile device and store the password in the keychain.
- Signup with the API using this login/password combination. This returns a token.
- Token is used in subsequent calls
The drawbacks are:
- Login/passwords can be lost if user deletes app (this could maybe be mitigated by using iCloud to store the login - but that would be bad for the password?)
- Password is stored on the device (however it's in the keychain)
So my questions: is something like this feasible and secure enough? Are there known techniques to do that?
Here's what we did:
Basically, the idea is pretty similar to the "forgot password" most services offer:
- Ask the user for an email
- Send an email with an activation link. The email contains a deeplink with a one time token, something like
myapp://login?token=.....
.
- User opens the email on the device where the app is installed this is crucial for the deep link to work, but it what happens on 99% of the cases anyway. The user clicks the button with the deeplink
- User is redirected back to the app, you extract the token from the deeplink on the app and send it to the server api to authenticate. After authentication is done, create a session for the user so they won't need to authenticate again
The good:
- More secure: Users don’t have to think of new passwords (which are usually too simple) and there is no risk of users reusing passwords. For us as developers, it offers a solution that has only one (and simple!) path of authentication that is easier to understand and hence to protect. Also, we don’t have to touch any user passwords / hashed passwords.
- Smoother onboarding flow to the user: if you pre-enter the email in the input field the login flow can be as short as 2 button clicks and they're in. (unless you wanna take their name / other details as well but that requires additional input fields in traditional login as well)
The less good :)
- Users might not be used to this flow very well and might wonder why they don't need a password. I would add a small link explaining "why we don't need passwords?"
- If app is deleted or the user logs out, they will need to use their email to log in again. This is less of a problem for mobile apps where users don't occasionally log out and in etc
I've already implemented this flow into our app, you can read a more in depth explanation here:
http://www.drzon.net/passwordless-login-in-mobile-apps/
Some more considerations:
- To make it more secure, make the token available to use one time only and also put an expiration on it (like an hour). You can also tie the token to the specific device by sending the server a unique device id of some kind along with the email address. This way the user can't simply forward the email to another person and he will open it instead
- About the deep link - I found that some email providers block the use of links with custom url schemes like
app://
. The way to overcome this is by making the link point to your server instead and redirect there to the actual deep link
https://myserver.com/login?token=...
---> myapp://login?token=...
Mozilla wrote about it as well here
This is very open ended, but generally: don't reinvent the wheel, use a standard solution such as OAuth and/or OpenID Connect (uses OAuth). This has the drawback that users might required to login via a WebView or similar to get a token, but you won't have to store the passwords.
Things to consider:
- you can't really generate a random password, since the server needs to know it as well
- Android doesn't have a public keychain-like API, so you have to take care of securing the password yourself.
As for 'secure enough', pretty much everyone uses OAuth nowadays(Twitter, Facebook, etc), so it's at least proven. The actual security will depend on your particular implementation.