I don\'t know if I just have some kind of blind spot or what, but I\'ve read the OAuth 2 spec many times over and perused the mailing list archives, and I have yet to find a
Here are my thoughts:
The purpose of auth code + token in authorization code flow is that token and client secret will never be exposed to resource owner because they travel server-to-server.
On the other side, implicit grant flow is for clients that are implemented entirely using javascript and are running in resource owner's browser. You do not need any server side code to use this flow. Then, if everything happens in resource owner's browser it makes no sense to issue auth code & client secret anymore, because token & client secret will still be shared with resource owner. Including auth code & client secret just makes the flow more complex without adding any more real security.
So the answer on "what has been gained?" is "simplicity".
The usual explanation is that the Implicit grant is easier to implement when you're using a JavaScript client. But I think this is the wrong way to look at it. If you're using a JavaScript client that requests protected resources directly via XMLHttpRequest, the Implicit grant is your only option, although it's less secure.*
The Authorization Code grant provides additional security, but it only works when you have a web server requesting the protected resources. Since the web server can store the access token, you run less risk of the access token being exposed to the Internet, and you can issue a token that lasts a long time. And since the web server is trusted, it can be given a "refresh token", so it can get a new access token when the old one expires.
But -- and this is a point that's easy to miss -- the security of the Authorization code flow works only if the web server is protected with a session, which is established with user authentication (login). Without a session, an untrusted user could just make requests to the web server, using the client_id, and it would be the same as if the user had the access token. Adding a session means that only an authenticated user can access the protected resources. The client_id is just the "identity" of the JS webapp, not authentication of said webapp.
It also means that you can end the session before the OAuth token expires. There's no standard way to invalidate an access token. But if your session expires, the access token is useless, since nobody knows it but the web server. If an untrusted user gained access to your session key, they would only be able to access the protected resources for as long as the session was valid.
If there's no web server, you have to use the Implicit grant. But this means that the access token is exposed to the Internet. If an untrusted user gains access to it, they can use it until it expires. This means they'll have access to it for longer than with an Authorization Code grant. So you may want to consider making the token expire sooner, and avoid giving access to more sensitive resources.
*EDIT: More recently, people are recommending that you avoid using the Implicit grant, even on web apps without a server. Instead you can use the Authorization Code grant configured with an empty secret, along with PKCE. The auth-code grant avoids storing the access token in your browser history, and PKCE avoids exposing it if someone hijacks the redirect URL to steal the auth code. In this case you would need the server to avoid returning a refresh token, since your client probably can't store it securely. And it should issue an access token with the same limitations mentioned above.
While Implicit Grant was designed to support apps that could not protect a client secret including client-side JavaScript apps, some providers are implementing an alternative using Authorization Code without a Client Secret instead. The OAuth 2.0 IETF RFC-6749 was published in 2012 and current recommendations some recent discussions are from 2017.
2017 discussion on the IETF OAuth mailing list is available from these implementers:
Read more here:
Implicit was previously recommended for clients without a secret, but has been superseded by using the Authorization Code grant with no secret.
...
Previously, it was recommended that browser-based apps use the "Implicit" flow, which returns an access token immediately and does not have a token exchange step. In the time since the spec was originally written, the industry best practice has changed to recommend that the authorization code flow be used without the client secret. This provides more opportunities to create a secure flow, such as using the state parameter. References: Redhat, Deutsche Telekom, Smart Health IT.
Moving to Auth Code without Client Secret from Implicit Grant is also mentioned for mobile apps here:
in addition to the other answers it is also important to realize that the Implicit profile allows for a front-channel only flow as opposed to the Authorization Code flow that requires a call back to the Authorization Server; this becomes evident in OpenID Connect which is an SSO protocol built on top of Auth 2.0 where the Implicit flow resembles the pretty popular SAML POST binding and the Authorization Code flow resembles the less widely deployed SAML Artifact binding
The Implicit Grant allows for obtaining tokens from Authorization Endpoint with a GET
. This means the authorization server does not have to support CORS.
If that is not a concern and there are no other issues related to the authorization server been inflexible (e.g. refresh tokens are not optional, for some reason) then authorization code flow is the preferred one, even for public clients, according to recent industry trends and to at least this (current) instance of an official draft.
Historically there were other reasons to implement the implicit flow but it seems they are currently outweighed by security advantages the authorization code grant provides, including:
It's there for security reasons, not for simplicity.
You should consider the difference between the user agent and the client:
The user-agent is the software whereby the user ("resource owner") communicates with other parts of the system (authentication server and resource server).
The client is the software which wants to access the resources of the user on the resource server.
In the case of decoupled user-agent and client the Authorization Code Grant makes sense. E.g. the user uses a web-browser (user-agent) to login with his Facebook account on Kickstarter. In this case the client is one of the Kickstarter's servers, which handles the user logins. This server gets the access token and the refresh token from Facebook. Thus this type of client considered to be "secure", due to restricted access, the tokens can be saved and Kickstarter can access the users' resources and even refresh the access tokens without user interaction.
If the user-agent and the client are coupled (e.g. native mobile application, javascript application), the Implicit Authorization Workflow may be applied. It relies on the presence of the resource owner (for entering the credentials) and does not support refresh tokens. If this client stores the access token for later use, it will be a security issue, because the token can be easily extracted by other applications or users of the client. The absence of the refresh token is an additional hint, that this method is not designed for accessing the user resources in the absence of the user.