# OAuth Authorization Code Grant

Learn how to log users in with the OAuth Authorization Code grant and PKCE.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

The Authorization Code grant is the recommended grant for logging users in. Your app redirects the browser to FusionAuth, and FusionAuth logs the user in. FusionAuth then redirects the browser back to your app with an authorization code. Your app exchanges the code for tokens.

```mermaid
sequenceDiagram
    participant Browser
    participant App as Your App
    participant FusionAuth
    Browser ->> App : Click log in
    App ->> Browser : Redirect to /oauth2/authorize with the code challenge
    Browser ->> FusionAuth : Request the login page
    FusionAuth ->> Browser : Redirect to the redirect URI with the authorization code
    Browser ->> App : Request the redirect URI
    App ->> FusionAuth : POST /oauth2/token with the code and the code verifier
    FusionAuth ->> App : Return the tokens
```

Requests between the browser, your app, and FusionAuth during an Authorization Code grant.

Before you start, configure the Application, as described in [Configure Application OAuth Settings](https://fusionauth.io/docs/authentication/oauth.md#configure-application-oauth-settings). Most apps use an OAuth library for these requests. To configure a library, see [Add Login to Your App](https://fusionauth.io/docs/authentication/oauth/add-login-to-your-app.md). The following example shows the raw requests. The example uses a FusionAuth instance at `https://piedpiper.fusionauth.io` and an app at `https://www.piedpiper.com`.

## Proof Key for Code Exchange

Use [Proof Key for Code Exchange](https://datatracker.ietf.org/doc/html/rfc7636) (PKCE, pronounced "pixie") with every Authorization Code grant. PKCE stops an attacker who intercepts the authorization code from exchanging the code for tokens.

Before each login, your app generates a random string called the code verifier. Your app hashes the code verifier with SHA-256 and sends the result to the authorize endpoint as the **`code_challenge`** parameter. FusionAuth stores the code challenge with the authorization code. When your app exchanges the code at the token endpoint, your app sends the original **`code_verifier`**. FusionAuth hashes the code verifier and rejects the request when the hash doesn't match the code challenge. An attacker who steals the code doesn't have the code verifier.

PKCE replaces the client secret for single-page and mobile apps, because a browser or a device can't keep a secret. Server-side apps send both. Most OAuth libraries generate the code verifier and the code challenge for you. To require PKCE for an Application, set **PKCE** to `Required` on the OAuth tab of the Application.

The following example uses the code verifier `dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk` and the code challenge `E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM`.

## Send the Browser to the Authorize Endpoint

To start a login, redirect the browser to the `/oauth2/authorize` endpoint. The example adds line breaks for readability.

Example Authorize URL

```plaintext
https://piedpiper.fusionauth.io/oauth2/authorize?
    client_id=06494b74-a796-4723-af44-1bdb96b48875
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &code_challenge_method=S256
    &redirect_uri=https%3A%2F%2Fwww.piedpiper.com%2Fcallback
    &response_type=code
    &scope=openid%20offline_access
    &state=abc123
    &tenantId=78dda1c8-14d4-4c98-be75-0ccef244297d
```

The URL uses the following parameters:

*   **`client_id`** is the **Client Id** from the OAuth tab of the Application.
*   **`code_challenge`** and **`code_challenge_method`** carry the PKCE code challenge.
*   **`redirect_uri`** is the URL that FusionAuth redirects the browser to after login. Add the URL to **Authorized redirect URLs** on the OAuth tab of the Application.
*   **`response_type`** is always `code` for this grant.
*   **`scope`** requests an [Id Token](https://fusionauth.io/docs/authentication/oauth/tokens.md#id-token) with `openid` and a [Refresh Token](https://fusionauth.io/docs/authentication/oauth/tokens.md#refresh-token) with `offline_access`.
*   **`state`** is a random value that your app stores before the redirect. Your app compares the value on the way back to block cross-site request forgery.
*   **`tenantId`** is the Id of the Tenant. FusionAuth uses the Tenant to pick the theme for the login page.

For every parameter, see the [Authorize endpoint](https://fusionauth.io/docs/apis/oauth/authorize.md).

## Handle the Redirect

After the user logs in, FusionAuth redirects the browser to the **`redirect_uri`**. The **`code`** parameter holds the authorization code:

Example HTTP Redirect Response

```plaintext
HTTP/1.1 302 Found
Location: https://www.piedpiper.com/callback?
    code=pU2DHOWjSCVh6NJKi1ClhBYNKfuqbZVT
    &iss=https%3A%2F%2Fpiedpiper.fusionauth.io
    &locale=en
    &state=abc123
    &userState=Authenticated
```

Before you use the code, check that **`state`** matches the value your app stored. Check that **`iss`** matches the Tenant **Issuer**, as described in [Issuer Validation](https://fusionauth.io/docs/authentication/oauth/issuer-validation.md). For the other parameters, see [Redirect Parameters](https://fusionauth.io/docs/apis/oauth/authorize.md#redirect-parameters).

## Exchange the Code for Tokens

Your app's server sends the code to the `/oauth2/token` endpoint. The **`client_secret`** authenticates your app, and the **`code_verifier`** completes PKCE. The example adds line breaks for readability.

Example HTTP Request

```plaintext
POST /oauth2/token HTTP/1.1
Host: piedpiper.fusionauth.io
Content-Type: application/x-www-form-urlencoded

client_id=06494b74-a796-4723-af44-1bdb96b48875
    &client_secret=example-client-secret-do-not-use
    &code=pU2DHOWjSCVh6NJKi1ClhBYNKfuqbZVT
    &code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
    &grant_type=authorization_code
    &redirect_uri=https%3A%2F%2Fwww.piedpiper.com%2Fcallback
```

You can send the Client Id and the client secret in an `Authorization: Basic` header instead of the body. A single-page or mobile app leaves out **`client_secret`**. Set **Client Authentication** on the OAuth tab of the Application to `Not required when using PKCE`, and FusionAuth accepts the code verifier in place of the secret. A single-page app without a backend can use the [hosted backend](https://fusionauth.io/docs/apis/hosted-backend.md) to make this request instead.

Replace the example client secret

`example-client-secret-do-not-use` is a placeholder. Don't use the placeholder in a real Application. Use the **Client secret** from the OAuth tab of your Application, and keep the secret on your server.

FusionAuth returns the tokens:

Example JSON Response

```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "expires_in": 3600,
  "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "refresh_token": "ze9fi6Y9sMSf3yWp3aaO2w7AMav2MFdiMIi2GObrAi-i3248oo0jTQ",
  "refresh_token_id": "4c8927f1-95cd-4bf8-9534-066389ffff5e",
  "scope": "openid offline_access",
  "token_type": "Bearer",
  "userId": "3b6d2f70-4821-4694-ac89-60333c9c4165"
}
```

For every request and response field, see the [Token endpoint](https://fusionauth.io/docs/apis/oauth/token.md).

## Check the User's Access

Validate the access token before your app trusts the claims. Most OAuth libraries validate tokens for you. For the claims in each token, see [Tokens](https://fusionauth.io/docs/authentication/oauth/tokens.md).

The **`roles`** claim lists the user's roles in the Application. FusionAuth adds the **`roles`** claim only when the user has a [Registration](https://fusionauth.io/docs/concepts/types/registrations.md) for the Application. When the user has no Registration, your app can reject the login or start a registration flow.

When your app needs more user data than the claims hold, send the access token to the [UserInfo endpoint](https://fusionauth.io/docs/apis/oauth/userinfo.md). With an API key, your app can retrieve the full User with the [Retrieve a User API](https://fusionauth.io/docs/apis/users/retrieve.md). The **`sub`** claim holds the User Id.

After the checks pass, log the user in to your app. A web app usually creates a session and stores the user in the session.

## Log Out

To log the user out, end the session in your app first. Then redirect the browser to the `/oauth2/logout` endpoint, which ends the FusionAuth session. The example adds line breaks for readability.

Example HTTP Request

```plaintext
GET /oauth2/logout?
      client_id=06494b74-a796-4723-af44-1bdb96b48875
      &tenantId=78dda1c8-14d4-4c98-be75-0ccef244297d HTTP/1.1
Host: piedpiper.fusionauth.io
```

FusionAuth redirects the browser to the **Logout URL** of the Application:

Example HTTP Response

```plaintext
HTTP/1.1 302 Found
Location: https://www.piedpiper.com
```

For every parameter, see the [Logout endpoint](https://fusionauth.io/docs/apis/oauth/logout.md).

Related

[Authentication Add FusionAuth Login to an App You Build Learn how to add FusionAuth login to a web, mobile, or single-page app you build with an OpenID Connect library and the OAuth Authorization Code grant. oauthoidcauthorization code grant](https://fusionauth.io/docs/authentication/oauth/add-login-to-your-app.md)

[APIs Authorize API API documentation for the FusionAuth Authorize OAuth2 endpoint. oauthauthorization code grantpkce](https://fusionauth.io/docs/apis/oauth/authorize.md)

[APIs Token API API documentation for the FusionAuth Token OAuth2 endpoint. oauthtoken endpointpkce](https://fusionauth.io/docs/apis/oauth/token.md)

[Authentication Authentication Learn how users and clients log in with FusionAuth, and how FusionAuth acts as an identity provider for other applications. loginoauthoidc](https://fusionauth.io/docs/authentication.md)
---

## Other pages in OAuth

> For the full index of this section, see [Authentication](https://fusionauth.io/docs/llms-authentication.txt).

- [Add FusionAuth Login to an App You Build](https://fusionauth.io/docs/authentication/oauth/add-login-to-your-app.md): Learn how to add FusionAuth login to a web, mobile, or single-page app you build with an OpenID Connect library and the OAuth Authorization Code grant.
- [CIMD Registration Caching And Lifecycle](https://fusionauth.io/docs/authentication/oauth/cimd-registration-lifecycle.md): Learn how long FusionAuth caches a Client ID Metadata Document, what happens when it expires, and how a CIMD client registration is refreshed or removed.
- [OAuth Client Credentials Grant](https://fusionauth.io/docs/authentication/oauth/client-credentials.md): Learn how to get an access token for machine-to-machine requests with the OAuth Client Credentials grant.
- [OAuth Client Registration | Static and CIMD](https://fusionauth.io/docs/authentication/oauth/client-registration.md): Learn how FusionAuth registers OAuth clients, either ahead of time as Applications or just-in-time from a Client ID Metadata Document.
- [OAuth Device Authorization Grant](https://fusionauth.io/docs/authentication/oauth/device.md): Learn how to log users in on TVs and other input-constrained devices with the OAuth Device Authorization grant.
- [Use DPoP In A Browser App](https://fusionauth.io/docs/authentication/oauth/dpop/browser-app.md): Learn how to bind tokens to the browser with DPoP using the FusionAuth React, Angular, or Vue SDK.
- [Demonstrating Proof-of-Possession (DPoP)](https://fusionauth.io/docs/authentication/oauth/dpop.md): Learn how DPoP binds FusionAuth access and refresh tokens to a key pair that only your client holds.
- [Validate DPoP Requests In Your API](https://fusionauth.io/docs/authentication/oauth/dpop/validate-requests.md): Learn how to check DPoP proofs and DPoP-bound FusionAuth access tokens in your API.
- [Host A Client ID Metadata Document (CIMD)](https://fusionauth.io/docs/authentication/oauth/host-cimd-document.md): Publish a Client ID Metadata Document so your OAuth client can log in to FusionAuth without being registered ahead of time.
- [OAuth](https://fusionauth.io/docs/authentication/oauth.md): Learn about the OAuth 2.0 and OpenID Connect grants FusionAuth supports for login and single sign-on.
- [OAuth Issuer Validation](https://fusionauth.io/docs/authentication/oauth/issuer-validation.md): Learn how to validate the authorization response issuer parameter (RFC 9207) to prevent mix-up attacks.
- [Legacy OAuth Implicit and Password Grants](https://fusionauth.io/docs/authentication/oauth/legacy-grants.md): Learn how the legacy OAuth Implicit and Password grants work in FusionAuth, for existing integrations.
- [Connect claude.ai And chatgpt.com To A FusionAuth-Protected MCP Server](https://fusionauth.io/docs/authentication/oauth/mcp-clients-claude-chatgpt.md): Learn how to connect claude.ai and chatgpt.com to an MCP server protected by FusionAuth using Client ID Metadata Documents.
- [Modes](https://fusionauth.io/docs/authentication/oauth/modes.md): Learn about the eight common ways apps use OAuth and OpenID Connect.
- [OIDC Prompt](https://fusionauth.io/docs/authentication/oauth/prompt.md): Learn about OpenID Connect prompt and example use cases.
- [OAuth Refresh Token Grant](https://fusionauth.io/docs/authentication/oauth/refresh-token.md): Learn how to exchange a refresh token for a new access token with the OAuth Refresh Token grant.
- [OAuth Response Modes](https://fusionauth.io/docs/authentication/oauth/response-modes.md): Learn about OAuth 2.0 response modes (query, fragment, form_post) and when to use each one.
- [Manage Software Tokens](https://fusionauth.io/docs/authentication/oauth/tokens.md): Learn about OAuth2 and OpenID Connect Tokens and how they are used.
- [URL Validation](https://fusionauth.io/docs/authentication/oauth/url-validation.md): Learn about OAuth URL validation policies in FusionAuth.
