Skip to main content
Category: OAuth & OIDC

Authorization Code Flow

Also known as: Authorization Code Grant, Auth Code Flow
Simply put

The Authorization Code Flow is a common way for an application to get permission to access resources on a user's behalf without ever handling the user's password. The user is sent to a trusted authorization server to approve access, and the application receives a short-lived code that it then exchanges for a token. This two-step exchange keeps the token out of the browser's address bar and makes the process more secure.

Formal definition

The Authorization Code Flow is an OAuth 2.0 grant type in which a client obtains delegated authorization to access protected resources. The resource owner (user) is redirected to the authorization server to grant consent, after which the authorization server returns an authorization code to the client's redirect URI; the client then exchanges that code at the token endpoint for tokens. Because the code-for-token exchange occurs on a back channel, this flow is typically recommended for confidential clients capable of securely storing a client secret. Public clients (for example single-page or native applications) commonly extend this flow with PKCE (Proof Key for Code Exchange) to mitigate authorization code interception, depending on configuration. Note that OAuth 2.0 governs delegated authorization rather than user authentication; when an ID token is required for authentication, this flow is used within OpenID Connect built on top of OAuth 2.0. The exact tokens returned and their handling vary by authorization server and profile.

Why it matters

The Authorization Code Flow is the most widely used OAuth 2.0 grant type, and it underpins a large portion of delegated-access scenarios that IAM teams design and operate. Its core value is that the application never handles the user's credentials directly: the user authenticates and grants consent at a trusted authorization server, and the application receives only a short-lived authorization code. This separation reduces the attack surface associated with credential handling and keeps tokens out of the browser's address bar, since the code-for-token exchange happens on a back channel rather than being exposed in a front-channel redirect.

For security architects and IAM engineers, choosing the right grant type is a foundational design decision that affects where secrets are stored, how tokens are protected in transit, and which client types can safely participate. The Authorization Code Flow is typically recommended for confidential clients that can securely store a client secret, while public clients such as single-page and native applications commonly extend it with PKCE to mitigate authorization code interception. Selecting an inappropriate flow, or omitting protections such as PKCE where they apply, can weaken an otherwise sound authorization architecture.

It is also important to keep the flow's scope clear: OAuth 2.0, including the Authorization Code Flow, governs delegated authorization rather than user authentication. When an application needs to authenticate the user and obtain an ID token, the flow is used within OpenID Connect, which is built on top of OAuth 2.0. Conflating the two leads to design and audit errors, so teams should be explicit about whether a given deployment is performing delegated authorization, authentication, or both.

Who it's relevant to

Security architects
Architects decide which OAuth 2.0 grant type fits a given client type and trust boundary. The Authorization Code Flow is the most widely used grant type and is typically recommended for confidential clients that can securely store a secret; architects should also account for PKCE when public clients participate, depending on configuration.
IAM engineers
Engineers implementing delegated access must correctly configure the redirect URI, the token endpoint exchange, and client credentials so that the code-for-token exchange occurs on the back channel. They also determine whether the deployment needs OpenID Connect on top of OAuth 2.0 when an ID token for authentication is required.
Application developers
Developers integrating web, single-page, or native applications need to know when to use the Authorization Code Flow and when to extend it with PKCE. Confidential applications can store a client secret, while public clients commonly rely on PKCE to mitigate authorization code interception.
Compliance and audit teams
Auditors reviewing access flows benefit from understanding that this flow keeps user credentials and tokens out of the browser, and that OAuth 2.0 governs delegated authorization rather than authentication. Distinguishing delegated authorization from authentication (via OpenID Connect) is important when assessing how access is granted and evidenced.

Inside Authorization Code Flow

Authorization Request
The initial redirect from the client to the authorization server's authorization endpoint, typically carrying response_type=code, client_id, redirect_uri, scope, and state parameters. This step is where the resource owner is prompted to authenticate and consent, though the authentication itself is performed by the authorization server, not the client.
Authorization Code
A short-lived, single-use credential returned to the client's redirect_uri after the resource owner grants consent. It is an intermediary artifact, not an access token, and is exchanged at the token endpoint. Because it travels through the user agent, it is intended to be of limited value if intercepted, especially when bound with PKCE.
Token Exchange (Token Endpoint)
The back-channel request in which the client exchanges the authorization code for tokens, typically presenting client credentials (for confidential clients) or a PKCE code_verifier. In OAuth 2.0 this yields an access token and optionally a refresh token; when OpenID Connect is layered on top, an ID token is also returned for authentication purposes.
state Parameter
An opaque value maintained between the request and callback to bind the response to the originating session, used to mitigate CSRF. It is distinct from the nonce used in OpenID Connect to bind an ID token to a specific authentication request.
PKCE (Proof Key for Code Exchange)
An extension that adds a code_challenge on the authorization request and a code_verifier on the token exchange, protecting against authorization code interception. Originally aimed at public clients such as native and single-page apps, PKCE is recommended for confidential clients as well in current guidance, depending on the profile in use.
Redirect URI
The pre-registered client endpoint to which the authorization server returns the authorization code. Exact matching of the registered redirect_uri is typically required to prevent code delivery to attacker-controlled endpoints.

Common questions

Answers to the questions practitioners most commonly ask about Authorization Code Flow.

Does the Authorization Code Flow authenticate the user?
Not by itself. The Authorization Code Flow is an OAuth 2.0 flow whose purpose is delegated authorization, obtaining an access token so a client can access protected resources on the resource owner's behalf. OAuth 2.0 alone is not an authentication protocol. To authenticate the user, you use OpenID Connect (which is layered on top of OAuth 2.0); in that case the flow additionally returns an ID token that conveys authentication claims about the user. The underlying user authentication itself happens at the authorization server, separately from the flow's authorization function.
Is the authorization code the same thing as an access token?
No. The authorization code is a short-lived, single-use intermediary credential returned to the client's redirect URI. The client must exchange it at the token endpoint to obtain tokens. That exchange typically returns an access token, and, depending on the request and grants, may also return a refresh token and, under OpenID Connect, an ID token. The code is a temporary handle used to keep tokens off the front channel (the browser redirect), not a token that grants resource access on its own.
Should confidential and public clients use the Authorization Code Flow differently?
In most deployments, yes. Confidential clients (such as server-side web applications) can authenticate to the token endpoint using a client secret or other client credentials. Public clients (such as single-page apps and native/mobile apps) cannot securely hold a secret, so they typically rely on PKCE to protect the code exchange. Current guidance commonly recommends PKCE for all client types, including confidential clients, depending on the authorization server's support and profile.
What does PKCE add to the Authorization Code Flow and when should it be used?
PKCE (Proof Key for Code Exchange) binds the authorization request to the token request so that an intercepted authorization code cannot be redeemed by an attacker. The client sends a code challenge on the authorization request and the corresponding code verifier on the token request, and the authorization server validates the match. It was originally introduced to protect public clients, but is now commonly applied to confidential clients as well, subject to authorization server support and the profile you are following.
Why does the token exchange happen on the back channel instead of the browser redirect?
Returning the authorization code (rather than tokens) on the front-channel redirect keeps tokens out of the browser address bar, history, referrer headers, and logs. The client then exchanges the code for tokens over a direct, typically server-to-server request to the token endpoint. This reduces token exposure compared with front-channel token delivery. The exact protections depend on transport security, client authentication or PKCE, and redirect URI validation as configured.
How should redirect URIs be handled to prevent code interception or misuse?
Authorization servers typically require redirect URIs to be pre-registered and match the request, often using exact-match comparison rather than partial or wildcard matching, to limit where an authorization code can be delivered. Combined with PKCE, single-use codes, short code lifetimes, and TLS, strict redirect URI handling reduces the risk of code interception and open-redirect abuse. Specific matching rules and allowed URI forms vary by authorization server and the profile in use.

Common misconceptions

The Authorization Code Flow authenticates the user for the client application.
OAuth 2.0 is a delegated authorization framework, and the Authorization Code Flow by itself grants access to resources; it does not authenticate the user to the client. User authentication is only obtained when OpenID Connect is layered on top and an ID token is issued. The authorization server authenticates the resource owner as part of the flow, but that assurance is not conveyed to the client through an access token alone.
The authorization code is itself a token that can be used to call APIs.
The authorization code is a short-lived, single-use intermediary credential that must be exchanged at the token endpoint. It is not an access token and cannot be presented to resource servers; it exists to keep tokens off the front channel.
PKCE is only needed for public clients that cannot hold a secret.
PKCE was introduced primarily for public clients such as native and single-page applications, but current guidance in many profiles recommends applying it to confidential clients as well to defend against authorization code interception, depending on the deployment and profile.

Best practices

Use the Authorization Code Flow with PKCE for both public and confidential clients where the profile supports it, rather than relying on client authentication alone to protect the code exchange.
Generate and validate the state parameter on every request to bind the callback to the originating session and mitigate CSRF, and when using OpenID Connect, validate the nonce to bind the ID token to the authentication request.
Register and enforce exact redirect_uri matching at the authorization server so codes cannot be delivered to attacker-controlled endpoints.
Treat authorization codes as single-use and short-lived; reject reused codes and keep them off any logs or referrer headers.
Perform the token exchange over the back channel and, for confidential clients, authenticate the client at the token endpoint according to the configured method.
When authentication of the user is required, layer OpenID Connect on top and consume the ID token for identity claims rather than inferring authentication from an access token.
Promotional banner for the Pentest Readiness checklist download