The authorization code flow is the most widely used OAuth flow. Authorization code flow is commonly used for webserver applications where the source code is not exposed and hence client secret (used for exchanging auth code with tokens) can be stored securely.It can also be used with spa with back end. For native apps or spa (with no back end) authorization code flow with pkce should be used.

Web apps are written in a server-side programming language and run on a web/appserver .The source code of the application is not public. This means that the application can safely use its client secret when communicating with the authorization server, ie the access Token is passed directly to client's webserver, without going through the user's web browser and hence access token will not be visible in browser history.  Even for native app/ spa with back end this flow can be used. (Native apps use browser to initiate authorization flow).

In the following example a user (resource owner) allready logged in to webapplication newservice.com (client) wants to authorize newsservice.com access to his google api (resource server)

Sequence diagram for authorizing webapp/spa with backend (for an authenticated user)

Here the assumption is that the user is only authorizing .(not authenticating). He is already logged in to the client application.(newsservice.com)

Step 1.a (Request to authorization end point)

https://google-auth-server.com/authorize?response_type=code& client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos&state=stxyxze

The authorization code flow begins with the client directing the user to the /authorize endpoint of the authserver. The request parameters are

When the authorization request reaches the authorization server the auth server will

authorize

If the user allows then the authorization service will redirect the user to redirect uri with auth code and state

Step 1.b (Response from authorization end point)

https://newsservice.com/redirectpage?code=AUTH_CODE&state=stxyxze

On receiving the redirect response  the client webserver server will

Step 2.a (Make POST request to token end point)

https://google-auth-server.com/token?grant_type=authorization_code& code=AUTH_CODE& redirect_uri=REDIRECT_URI& client_id=CLIENT_ID& client_secret=CLIENT_SECRET

The client webserver will typically initiate a POST request to token end point to get access and/or id token with

Step 2.b (The token end point responds with access token and refresh token )

Step 3 - client uses access token to interact with resource server.

Now that access_token is acquired,it can use the token in requests to resouce server web APIs by including it in the Authorization header:

When the resouce server receives the request with access token,it will make a hit to token introspection end point ( in case of opaque access token).If the token is expired resouce server will return error which should be handled by client . (the client could use the refresh token to get another access token).

note that as per the spec

The resource server MUST validate the access token and ensure it has not expired and that its scope covers the requested resource. The methods used by the resource server to validate the access token (as well as any error responses) are beyond the scope of this specification, but generally involve an interaction or coordination between the resource server and the authorization server.

The reason why the spec does not cover how the access token is validated is that the interaction between resource server and authorization server is dependent upon the architecture of the deployment. For instance the authorization service and resource server may the the same or it may be distributed.

If the token is self contained jwt token then no need to hit token introspection end point.

Attacks (CSRF/REPLAY)

Both authorization code injection attack (via CSRF on genunine user's browser) and authorization code repaly attack on attacker's browser  can be blocked by establishing request and response co-relation via the state parameter.