Password-Less User Authentication

I’m what you might call a client-side iOS programmer, but for my latest project I’ve decided to roll my own backend. I’ve been thinking about the authentication flow will be needed. I don’t want users to remember usernames/passwords, and I don’t really want to have to keep track of them.

Currently, for development, the backend just checks for a single unique token that the client must send with all requests. (Assume that I’m using SSL Pinning to ensure that I’m not connecting to a man in the middle.) This is okay when the app is just on my phone, but I can’t very well ship the app with the token embedded. Even if it’s obfuscated, there’s no guaranteed way to prevent someone from unearthing the token and making rogue API requests. And by rogue API request, I mean any API request that’s not a result of normal use of the app.

It really wouldn’t be the end of the world if this happened. The only consequences I can think of is my database filling up with junk, or maybe someone could try to brute force their way into getting some semi-sensitive data out of the API.

So anyway, I’d like to have some per-user, or per-device, token that I can use to authenticate API requests. I’m thinking of trying the following password-less approach:

  • User is prompted to enter an email to sign up for an account. At this time, a unique token is generated and sent to the API along with the email address. Token is stored in the keychain on the device.
  • User is prompted to check his email to continue. Offer a button to open Mail.app, GMail.app, or another mail app that’s been detected.
  • Meanwhile, at the backend, an email is generated with a unique URL and sent to the user. Tapping this link will whitelist the token generated in (1), and kick the user back into the app.
  • From now on, whenever the app becomes active, it queries the API to test if the token is whitelisted. If a good token is not found in the keychain, then the app can go through the flow again to generate one. And this would give me a mechanism for blocking a token or email address that is acting suspiciously.

So this would let the app authenticate with the API without the need for a password. The downside is that the user will have to go through this flow on every new device. Perhaps I could store the token in iCloud to avoid that problem.

Questions:

  • Is this a horrible idea? Could I somehow achieve this with OAuth?
  • Does it matter if the token is generated client-side or server-side?