# OAuth2 Authorization Code Flow

OAuth2 and OpenID Connect are widely used authorization and authentication delegation protocols that enable secure access to APIs and web applications. This document explains how to obtain ID tokens and refresh tokens, and also discusses various parameters, such as `grant_type`, `redirect_uri`, `prompt`, `scope`, `state`. Additionally, this document describes how to perform PKCE on top of the Authorization Code flow.

The Authorization Code flow is the most secure and widely used OAuth2 flow for web applications. Here is the high-level overview of the Authorization Code flow:

1. The user clicks on a link or button on a web page that requests access to a resource.
2. The user is redirected to the Authorization Server, where they authenticate themselves and grant permission to the requesting application.
3. The Authorization Server generates an authorization code and redirects the user back to the requesting application with the authorization code.
4. The requesting application exchanges the authorization code for an access token that can be used to access the protected resource.

## Step 1: Get the user's permission

The user clicks on a link or button on a web page that requests access to a resource. The requesting application sends a request to the Authorization Server with the following parameters:

- `response_type`: The value of this parameter should be set to `code` to indicate that the Authorization Code flow will be used.
- `client_id`: The ID of the client that is making the request.
- `redirect_uri`: The URL where the Authorization Server will redirect the user after they grant permission. The `redirect_uri` needs to be pre-registered with the OAuth2 client.
- `state`: A random value that is generated by the requesting application to prevent cross-site request forgery (CSRF) attacks.
- `prompt` (optional): This parameter takes one or more of the following values (space delimited):
  - `none`: This value indicates that the Authorization Server should not display any user interaction pages. If the user is not already authenticated or has not already granted consent, the Authorization Server returns an error.
  - `login`: This value indicates that the Authorization Server should prompt the user to login before processing the access request.
  - `select_account`: This value indicates that the Authorization Server should prompt the user to select a user account.
  - `consent`: This value indicates that the Authorization Server should prompt the user to grant consent before processing the access request.
  - `registration`: This value indicates that the Authorization Server should display the registration UI instead of the login UI.
- `scope` (optional): The scope of the access request, which specifies what resources the requesting application can access.
- `max_age` (optional): Specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by Ory OAuth2 and OpenID Connect.
- `id_token_hint` (optional): ID Token previously issued by Ory OAuth2 and OpenID Connect being passed as a hint about the user's current or past authenticated session with the Client.

## Step 2: Redirect to the Authorization Server

The user is redirected to the Authorization Server, where they authenticate themselves and grant permission to the requesting application. The Authorization Server could ask the user to log in or prompt them to authorize the access request.

## Step 3: Redirect back to the app

If the user grants permission, the Authorization Server generates an authorization code and redirects the user back to the requesting application with the authorization code.

## Step 4: Exchange code for token

The requesting application exchanges the authorization code for an access token that can be used to access the protected resource. The requesting application sends a POST request to the Authorization Server with the following parameters:

- `grant_type`: The value of this parameter should be set to `authorization_code` to indicate that the authorization code will be exchanged for an access token.
- `client_id`: The ID of the client that is making the request.
- `client_secret`: The client secret that is used to authenticate the client.
- `code`: The authorization code that was received in the previous step.
- `redirect_uri`: The URL where the Authorization Server redirected the user after they granted permission.

The Authorization Server validates the request and responds with an access token and a refresh token (if enabled). The requesting application can use the access token to access the protected resource.

## Modifying the authorization code flow

### Get a refresh token

By default, the Authorization Code flow returns an access token that expires after a certain period of time. To get a refresh token, you need to include the `offline_access` scope in the access request.

### Get an OpenID Connect ID token and validate it

To obtain an ID token, you need to include the `openid` scope in the access request. The ID token is a JSON Web Token (JWT) that contains information about the authenticated user. The ID token can be used to obtain information about the user such as their name and email address.

To validate the ID token, you need to decode the JWT and verify the signature using the public key of the Authorization Server which is available at

```
https://$PROJECT_SLUG.projects.oryapis.com/.well-known/jwks.json
```

## Perform PKCE

PKCE (Proof Key for Code Exchange) is a security extension to the Authorization Code flow that is designed to prevent code injection attacks. In the PKCE flow, the client generates a random code verifier and transforms it into a code challenge that is sent to the Authorization Server.

Here's a JavaScript code example that demonstrates how to generate a code verifier and code challenge using the SHA-256 hash algorithm:

```js
// Generate PKCE code challenge and verifier

async function generatePKCES256() {

const array = new Uint8Array(64)
  crypto.getRandomValues(array)
  const codeVerifier = Buffer.from(array).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\/g, "_")

const codeChallenge = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(codeVerifier)).then((buffer) => {
    return Buffer.from(buffer).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\/g, "_")
  })

return { codeChallenge, codeVerifier }
}

const { codeChallenge, codeVerifier } = await generatePKCES256()

const redirectUri = "..."
const clientId = "..."

// Send the code challenge along with the authorization request
const authorizationUrl = `https://$PROJECT_SLUG.projects.oryapis.com/oauth2/auth?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&code_challenge=${codeChallenge}&code_challenge_method=S256`

// Exchange the authorization code for a token using the code verifier
const code = new URLSearchParams(window.location.search).get("code")
const tokenUrl = "https://$PROJECT_SLUG.projects.oryapis.com/oauth2/token"
const tokenRequestBody = new URLSearchParams({
  grant_type: "authorization_code",
  client_id: clientId,
  redirect_uri: redirectUri,
  code_verifier: codeVerifier,
  code: code,
})

fetch(tokenUrl, {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: tokenRequestBody.toString(),
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error))
```

In this example, `generatePKCES256()` generates a random code verifier with a length of 64 characters, as well as the base64url-encoded SHA-256 hash of the code verifier as the code challenge.

## Examples

This section demonstrates how to use Ory OAuth2 and OpenID Connect in different types of web applications. The examples cover the use of public clients with PKCE, confidential clients, custom redirect schemes in mobile/native apps, and more.
