This is the most complete and complex flow. The login process is divided into two phases, which ensure greater security.

The involved actors

User : the person who wants to be authenticated, to access protected information.

: the person who wants to be authenticated, to access protected information. Client App : In this flow, the client is usually a web application. The application must have both a front-end and a back-end, later we’ll see why. This means a pure Front-end application (Javascript, React, Angular) cannot implement this flow but can use the Implicit grant one.

: In this flow, the client is usually a web application. The application must have both a front-end and a back-end, later we’ll see why. This means a pure Front-end application (Javascript, React, Angular) cannot implement this flow but can use the Implicit grant one. Authorization Server : is the component that performs the authentication and the authorization, it handles login requests, user authentication, token generation, and security validations.

: is the component that performs the authentication and the authorization, it handles login requests, user authentication, token generation, and security validations. Resource Server: it exposes resources, as they could be REST API. After the Client App obtains the access_token, it will use it to call the Resource Server. One of the differences between the Authorization Server and the Resource Server is that the first one “only” handles authentication and authorization, and the second one “only” serves the content (the resources). This division can generate some confusion: it’s important to remember this is a logic difference and not an implementation rule.

The flow

Let’s see in detail the Authorization code grant flow.

1. The user wants to log in

The classic scenario for this flow is played in the user browser. The user will click the “Login with OAuth” button and the client will generate and send a login request to the Authorization Server.

2. The user is redirected to the Authorization Server

The client generates a login request for the Authorization Server. The request will be sent in the form of an HTTP Redirect and the information will be sent as GET parameters.

GET /token Location: https://the-authorization-server/token?client_id=[the_client_id]&redirect_uri=[a redirect uri]&response_type=code&scope=[list of scopes]&state=[some client parameter]

The parameters are the following:

client_id : to identify the calling application

: to identify the calling application redirect_uri : the URL to which the Authorization Server will send (through a redirect) the Authorization code, after the user login.

: the URL to which the Authorization Server will send (through a redirect) the Authorization code, after the user login. response_type : identifies the type of response the Authorization Server will return. The value code is the one usually in the Authorization code flow.

: identifies the type of response the Authorization Server will return. The value is the one usually in the Authorization code flow. scope : a list of permits the application asks the user. For example: read_email, write_post. The user will be asked to grant those permits. This will be useful when the client will access the Resource Server. This one will decide if permit o deny the access. For example, a client, logging in with Facebook, ask the email scope. If the client (once obtained the token) calls the /{user-id}/friendlists API, that needs the friend_list scope, will obtain an access denied error.

: a list of permits the application asks the user. For example: read_email, write_post. The user will be asked to grant those permits. This will be useful when the client will access the Resource Server. This one will decide if permit o deny the access. For example, a client, logging in with Facebook, ask the scope. If the client (once obtained the token) calls the API, that needs the scope, will obtain an access denied error. state: this optional parameter will be returned as-is to the client, after the login process. It can be used to retrieve information on the client’s application about, for example, to the user session.

3. Request validation

L’Authorization Server must validate all the request parameters:

client_id : Does a client exist with this id? Is the client allowed to perform this request?

: Does a client exist with this id? Is the client allowed to perform this request? redirect_uri : Can the client use this redirect URI? Is this redirect URI associated with this client?

: Can the client use this redirect URI? Is this redirect URI associated with this client? response_type : Is the client allowed to use this response type?

: Is the client allowed to use this response type? scope: Is the client allowed to use these grants?

To execute these validations the Authorization server must have previously registered all the clients that will access. The onboarding and the maintenance of clients are out of the OAuth scope.

4. Login form

The Authorization server shows the login form, and the user has to insert the username and password, to make the login (step 5 in the picture).

After validating the data (step 6 in the picture) the Authorization server asks the user the consents specified in the scopes. The user will decide to grant, or not, one or more of the scopes. On the contrary case, the client will act differently. For example, it could limit or inhibit the use of the application.

7. Redirect to the client with the authorization_code

The Authorization Server generates an authorization code (authorization_code) and sends it to the client, to the URI specified in the request.

All these operations have happened client-side, on a browser (or a mobile app) for the next steps the client must use a back-end.

This, in my opinion, is one of the aspects to consider when you choose which OAuth 2 flow best fits your needs.

8 and 9. Authorization code validation

Now the client has to call the Authorization Server to validate the received code. To do this operation it will pass:

the authorization_code to be validated.

to be validated. the client_id : this is needed, along with the client_secret, to be sure the request comes from that client, and the token is not “stolen” when you were on the front-end.

: this is needed, along with the client_secret, to be sure the request comes from that client, and the token is not “stolen” when you were on the front-end. the client_secret is the client password, and it must be stored in a safe place, this is why you need a back-end.

The Authorization Server executes all the above validations, checking the authorization_code is intact, not altered, not expired and issued for that specific client.

10. The client receives the access_token

The Authorization server creates an access_token and returns it to the client. There are many types of token, they have an expiration date and they can be refreshed. Usually, along with the token, are returned some more information:

the token_type: one of the most famous is Bearer, which means: grant access to the bearer of this token. mac is another type.

expires_in: the duration of the token

refresh_token: another token, to renew the access_token when it expires.

11. The client uses the access_token.

Now that the client has obtained the access_token, it can use it to authenticate itself against the Resource Server.

The Resource Server is a generic component and could serve many different types of resources: REST API, SOAP Services, Web pages, etc… Based on the resource type, the method to send the access_token can change. The most common way to send it against REST API is to use the HTTP header: Authorization, concatenating the token_type with access_token. Example:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ

12 and 13. Token validation

When the Resource Server receives a request must check the token presence and integrity.

The token validation, especially based on its type, can be done in many ways. In some cases the Resource Server can validate it, in some other must call the Authorization server.

In some scenarios is possible that these two components are the same application, this is transparent and not important for the client. If you need to implement an OAuth server the choice on how to validate the token will vary based on your architecture and on the token type you’ll decide to use.

14 and 15. Access and display protected resources.

Once the Resource server validates the token successfully, it will return the resource to the client, and this can display it to the user.