# Roles and the Authorization Code Flow With PKCE — Authentication & Authorization

Source: https://www.skillbyai.com/en/authentication/o-code-pkce

> The recommended flow for web, mobile and single-page apps.

## Four roles, one redirect dance

OAuth 2.0 (RFC 6749) defines the **resource owner** (the user), the **client** (the app), the **authorization server** (issues tokens) and the **resource server** (the API). In the **authorization code flow** the client redirects the browser to the authorization server; the user logs in and consents; the server redirects back with a short-lived **code**; the client exchanges the code at the **token endpoint** for tokens over a back channel. **PKCE** (RFC 7636) binds the code to the client that started the flow: the client creates a random `code_verifier`, sends its SHA-256 hash as `code_challenge` (method `S256`), and must present the verifier when redeeming the code, so a stolen code is useless. Current guidance (RFC 9700, the OAuth 2.0 Security Best Current Practice) recommends PKCE for all clients, a random `state` to tie the response to the request, and exact matching of registered redirect URIs.

## Delegated access and federated login

OAuth 2.0 lets an application obtain limited access to an API on a user's behalf; OpenID Connect adds a standard identity layer for login.

![Three ideas: authorization code flow with PKCE, ID tokens versus access tokens, client credentials and deprecated grants.](assets/figures/authentication/section-5-map.svg) — Figure 5.1 — Client, authorization server, user, resource server.

## The flow on the wire

Simplified HTTP; values are illustrative.

```http
# 1. Browser is redirected to the authorization server
GET https://auth.example.com/authorize?response_type=code
    &client_id=web-app
    &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
    &scope=openid%20profile%20orders%3Aread
    &state=af0ifjsldkj
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &code_challenge_method=S256

# 2. After login and consent, the browser comes back
GET https://app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

# 3. Client exchanges the code (back channel)
POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
&client_id=web-app&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

# 4. Response
{ "access_token": "...", "token_type": "Bearer", "expires_in": 600,
  "refresh_token": "...", "id_token": "eyJ..." }
```

## A valet key with a claim ticket

OAuth gives the app a valet key that opens only some doors, instead of your master key (your password). PKCE is like keeping the stub of the claim ticket: someone who grabs the ticket alone cannot collect the car.

**Quiz:** What does PKCE protect against?

- [ ] Weak user passwords
- [x] An intercepted authorization code being redeemed by another party
- [ ] Expired access tokens
- [ ] Cross-site scripting in the API

*Answer:* An intercepted authorization code being redeemed by another party. Only the client holding the code_verifier can redeem the code.
