AuthenticationViewController
AuthenticationViewController copied to clipboard
Authentication Flow [Important Read]
Has brought up by @edjiang on https://twitter.com/EdwardStarcraft/status/712727368788353024 which authentication flow should we use for this library?
Would love some feedback
Hey Raul,
Thanks for opening up this issue! I've started working on (and thinking a lot more about) auth in the last two months, and I'm trying to really understand how AuthenticationViewController
, and a few other iOS OAuth libraries work.
OAuth 2 specifies several different types of grant_types
, which are meant to be used in different scenarios:
- Authorization Code - where you redirect a user to a login page, it redirects back with an authorization code, and you submit it to the OAuth server along with your client id and secret for an access token.
- Implicit - where you redirect a user to a login page, and it redirects back to your app with an access token.
- Password - where you POST the user's password to the OAuth server and get an access token.
- Client Credentials - used for server-to-server communication.
We're never going to use the password grant type, as providers won't trust us with their user's passwords as that's a huge phishing risk. Also, we'll never be using client credentials in our apps.
That leaves the Authorization Code and Implicit grant types.
The Authorization Code grant type is intended to be a server-side flow, as you need a client secret to use it. For instance, from the Instagram API docs:
Since an app can be decompiled, or HTTP requests can be intercepted, an end user can find out the client secret, which is bad since it enables anyone to perform operations that are meant to only be used from a server. For instance, in the Instagram case, a malicious user could view and modify the app's subscriptions to user data.
The implicit grant type gets rid of the token exchange and need for the client secret, but unfortunately is supported by fewer OAuth providers.
I'm not sure it's a good idea to be encouraging people to put client secrets (or implement the authorization code flow in-app) in a production application, but I'm open to understanding how security is handled here. Otherwise, I definitely see the convenience to using the auth code flow for testing (for providers that don't support implicit), but warning people not to use it in production.
TLDR: Auth code flow (implemented by AuthViewController) requires the client secret, which shouldn't be embedded in the app.
Would using Implicit give the app full access to the user account? user based limit and not client based limit? If so, then I will definitely open a ticket to fix that.
Looks like you are correct though, I will test it out to see if I get the same results.
Implicit should give the app reasonable access to the account. Some actions are still only going to be server-side.
The main problem is that some OAuth providers only support the authorization code flow, so won't be supported if you switch this to the implicit flow. But I would only recommend the authorization code flow for testing / development purposes, and never for production anyways.
Ok, after reading all of this, there is nothing really forcing AuthenticationViewController to use the 3 steps or the 2 steps. If you want to do only the Client Flow with Instagram all you need to do is skip the call to authenticateWithCode:
and since you have control over which endpoints you call with the Provider
protocol, you are completely free to do it however works best for your app.
But like you mentioned, very few providers support this 2 step flow instead of the full 3.