ChatGPT解决这个技术问题 Extra ChatGPT

What is the difference between the OAuth Authorization Code and Implicit workflows? When to use each one?

OAuth 2.0 has multiple workflows. I have a few questions regarding the two.

Authorization code flow - User logs in from client app, authorization server returns an authorization code to the app. The app then exchanges the authorization code for access token. Implicit grant flow - User logs in from client app, authorization server issues an access token to the client app directly.

What is the difference between the two approaches in terms of security? Which one is more secure and why?

I don't see a reason why an extra step (exchange authorization code for token) is added in one work flow when the server can directly issue an Access token.

Different websites say that Authorization code flow is used when client app can keep the credentials secure. Why?


E
Eugenio Pace

The access_token is what you need to call a protected resource (an API). In the Authorization Code flow there are 2 steps to get it:

User must authenticate and returns a code to the API consumer (called the "Client"). The "client" of the API (usually your web server) exchanges the code obtained in #1 for an access_token, authenticating itself with a client_id and client_secret It then can call the API with the access_token.

So, there's a double check: the user that owns the resources surfaced through an API and the client using the API (e.g. a web app). Both are validated for access to be granted. Notice the "authorization" nature of OAuth here: user grants access to his resource (through the code returned after authentication) to an app, the app get's an access_token, and calls on the user's behalf.

In the implicit flow, step 2 is omitted. So after user authentication, an access_token is returned directly, that you can use to access the resource. The API doesn't know who is calling that API. Anyone with the access_token can, whereas in the previous example only the web app would (it's internals not normally accessible to anyone).

The implicit flow is usually used in scenarios where storing client id and client secret is not recommended (a device for example, although many do it anyway). That's what the the disclaimer means. People have access to the client code and therefore could get the credentials and pretend to become resource clients. In the implicit flow all data is volatile and there's nothing stored in the app.


Thanks for your explanation but I don't understand why we need another Authorization Code flow. We can reach same result on server by implicit flow (access_token) and a refresh token. It looks the only security consideration of implicit flow is that access_code should have short life so it can't be used on server to server. OK, but the refresh token solve this problem. Why we should use an auth_code flow and request access_token by that on server to obtain access_code?
Well...it is how the protocol works. You might want to read the spec threat analysis for a more detailed reference on the security merits of one and the other.
I know the original answer is more than 5 years old, but this is the simplest and cleanest explanation I have ever read. Thank you @EugenioPace
@Madnik7G The reason is orthogonal to what this answers explains (beautifully): there might be a third party involved. The entire flow is orchestated by a user-agent (e.g: the browser), but in the end the authorization server (e.g: "Login with Facebook") will talk directly with the client (say, your server-side BFF) that will ultimately access the resource, so that the user-agent never has direct access.
Thanks! Yes, there're 3 communications taking place: the browser and the AS 9e.g. Facebook). That is the /authorize request. The browser and the web site trying to call the API (a.k.a. the client). That is the redirect_uri + code returned by the AS after successful authentication. Finally, the client calling the AS behind the scenes, exchanging the code for an access_token. This is the token endpoint in the literature. In general the AS never calls anyone. It always replies.
M
Michael Freidgeim

I'll add something here which I don't think is made clear in the above answers:

The Authorization-Code-Flow allows for the final access-token to never reach and never be stored on the machine with the browser/app. The temporary authorization-code is given to the machine with the browser/app, which is then sent to a server. The server can then exchange it with a full access token and have access to APIs etc. The user with the browser gets access to the API only through the server with the token.

Implicit flow can only involve two parties, and the final access token is stored on the client with the browser/app. If this browser/app is compromised so is their auth-token which could be dangerous.

tl;dr don't use implicit flow if you don't trust the users machine to hold tokens but you do trust your own servers.


re: The user with the browser gets access to the API only through the server with the token. But the server needs to send something to the browser so that the inbound requests can be associated to the token which is held server-side. A cookie if you like. If the server does not transmit the token to the JS running in the browser, it must transmit something else, that the (browser) client needs to pass to the server, in order to allow the server to act on behalf of the particular client.
Yes, a cookie. Thus, you should set up your server and browser client to be protected against cross-site request forgery.
@Marcel I would like to know that once we get the code, how and where the exchange happens to get the actual access_token with the help of authorization code.
In case of implicit, when end user is using a mobile app or a browser, then does the auth server return the auth code (which the browser redirects to the SPA and then SPA asks auth server for access token, followed by browser storing the access token) or does the auth server return the access token which is redirected to the SPA?
d
divyanshm

The difference between both is that:

In Implicit flow,the token is returned directly via redirect URL with "#" sign and this used mostly in javascript clients or mobile applications that do not have server side at its own, and the client does not need to provide its secret in some implementations. In Authorization code flow, code is returned with "?" to be readable by server side then server side is have to provide client secret this time to token url to get token as json object from authorization server. It is used in case you have application server that can handle this and store user token with his/her profile on his own system, and mostly used for common mobile applications.

so it is depends on the nature of your client application, which one more secure "Authorization code" as it is request the secret on client and the token can be sent between authorization server and client application on very secured connection, and the authorization provider can restrict some clients to use only "Authorization code" and disallow Implicit


Authorization code is stored in the server side for 10 minutes for facebook. This was released in their December 5,2012 change. My question mainly is, what's the difference between the 2 in terms of security/performance. I know what both the flows do - but what's the advantage of using authorization code - adding one more step to the workflow.
its not sending the token to user application direct the connection between client application and authorization server is hidden from user, and as I mentioned it could be very secured channel not the same as the one from user to client application.
performance in Authorization code you hit the auth server twice so it is taking more time, also the client server is going to store user token and this will add more time too.
Ohh okay! I might have overlooked this. So basically, authorization code flow is to be used by systems where an entire server is a client - the browser makes the request and gets the code. code is sent to the client server that connects to the resource server securely. Am I understanding it correctly? The access token never reaches the end-user's machine?
The access token never reaches the end-user's machine? yes, it is linked to your profile with the client application server.
A
Alireza Fattahi

Which one is more secure and why?

Both of them are secure, it depends in the environment you are using it.

I don't see a reason why an extra step (exchange authorization code for token) is added in one work flow when the server can directly issue an Access token.

It is simple. Your client is not secure. Let's see it in details.

Consider you are developing an application against Instagram API, so you register your APP with Instagram and define which API's you need. Instagram will provide you with client_id and client_secrect

On you web site you set up a link which says. "Come and Use My Application". Clicking on this your web application should make two calls to Instagram API.

First send a request to Instagram Authentication Server with below parameters.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

You don't send client_secret, You could not trust the client (The user and or his browser which try to use you application). The client can see the url or java script and find your client_secrect easily. This is why you need another step.

You receive a code and state. The code here is temporary and is not saved any where.

Then you make a second call to Instagram API (from your server)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

As the call is made from our server we can safely use client_secret ( which shows who we are), with code which shows the user have granted out client_id to use the resource.

In response we will have access_token


Here, once you get the access token, who will send it to Instagram again for API calls? the client and his browser ? or our server side app?
L
Lutfor

The implicit grant is similar to the authorization code grant with two distinct differences.

It is intended to be used for user-agent-based clients (e.g. single page web apps) that can’t keep a client secret because all of the application code and storage is easily accessible.

Secondly instead of the authorization server returning an authorization code which is exchanged for an access token, the authorization server returns an access token.

Please find details here http://oauth2.thephpleague.com/authorization-server/which-grant/


Thanks for that link, it helped me understand the difference between each grant type and when to choose each one.
C
Community

Let me summarize the points that I learned from above answers and add some of my own understandings.

Authorization Code Flow!!!

If you have a web application server that act as OAuth client

If you want to have long lived access

If you want to have offline access to data

when you are accountable for api calls that your app makes

If you do not want to leak your OAuth token

If you don't want you application to run through authorization flow every time it needs access to data. NOTE: The Implicit Grant flow does not entertain refresh token so if authorization server expires access tokens regularly, your application will need to run through the authorization flow whenever it needs access.

Implicit Grant Flow!!!

When you don't have Web Application Server to act as OAuth Client

If you don't need long lived access i.e only temporary access to data is required.

If you trust the browser where your app runs and there is limited concern that the access token will leak to untrusted users.


In case of implicit, when end user is using a mobile app or a browser, then does the auth server return the auth code (which the browser redirects to the SPA and then SPA asks auth server for access token, followed by browser storing the access token) or does the auth server return the access token which is redirected to the SPA?
C
Community

From practical perspective (What I understood), The main reason for having Authz code flow is :

Support for refresh tokens (long term access by apps on behalf of User), not supported in implicit: refer:https://www.rfc-editor.org/rfc/rfc6749#section-4.2 Support for consent page which is a place where Resource Owner can control what access to provide (Kind of permissions/authorization page that you see in google). Same is not there in implicit . See section : https://www.rfc-editor.org/rfc/rfc6749#section-4.1 , point (B)

"The authorization server authenticates the resource owner (via the user-agent) and establishes whether the resource owner grants or denies the client's access request"

Apart from that, Using refresh tokens, Apps can get long term access to user data.


K
KwaXi

Implicit grant should not be used anymore, see the IETF current best practices for details. https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-18#section-2.1.2

As an alternative use a flow with response type code; for clients without possibility to securely store client credentials the authorization code with PKCE flow should be your choice.


C
Community

There seem to be two key points, not discussed so far, which explain why the detour in the Authorization Code Grant Type adds security.

Short story: The Authorization Code Grant Type keeps sensitive information from the browser history, and the transmission of the token depends only on the HTTPS protection of the authorization server.

Longer version:

In the following, I'll stick with the OAuth 2 terminology defined in the RFC (it's a quick read): resource server, client, authorization server, resource owner.

Imagine you want some third-party app (= client) to access certain data of your Google account (= resource server). Let's just assume Google uses OAuth 2. You are the resource owner for the Google account, but right now you operate the third-party app.

First, the client opens a browser to send you to the secure URL of the Google authorization server. Then you approve the request for access, and the authorization server sends you back to the client's previously-given redirect URL, with the authorization code in the query string. Now for the two key points:

The URL of this redirect ends up in the browser history. So we don't want a long lived, directly usable access token here. The short lived authorization code is less dangerous in the history. Note that the Implicit Grant type does put the token in the history. The security of this redirect depends on the HTTPS certificate of the client, not on Google's certificate. So we get the client's transmission security as an extra attack vector (For this to be unavoidable, the client needs to be non-JavaScript. Since otherwise we could transmit the authorization code via fragment URL, where the code would not go through the network. This may be the reason why Implicit Grant Type, which does use a fragment URL, used to be recommended for JavaScript clients, even though that's no longer so.)

With the Authorization Code Grant Type, the token is finally obtained by a call from the client to the authorization server, where transmission security only depends on the authorization server, not on the client.