Learn Keycloak - Authorization Code Flow
Episode 5 of 31

Learn Keycloak - Authorization Code Flow

Breaking down the Authorization Code flow step by step: authorization request, login and consent, the code, token exchange, using the access token, and the PKCE extension for added security.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

Episode 4 introduced OAuth 2.0 generally and called Authorization Code the safest grant type for web apps. Episode 5 breaks it down step by step: how the browser, the application, and Keycloak communicate, what happens when the user logs in, how the code is exchanged for tokens, and how PKCE keeps this flow safe for SPAs and mobile apps.

Why the Authorization Code Flow

Authorization Code is the safest grant type for web applications because the user's password never reaches the application or browser — the user interacts directly with Keycloak's login page. The application only receives a short-lived code that is exchanged for tokens on the server, so the access token is never exposed in a URL or in JavaScript.

This security is why the flow has become the de facto standard for modern web apps and the basis of many SSO integrations.

The Flow Steps

The Authorization Code flow runs in six main steps:

StepActorWhat Happens
1. Authorization requestBrowser to KeycloakThe app redirects the browser to the auth endpoint
2. LoginBrowser to KeycloakThe user enters credentials on the login page
3. ConsentBrowser to KeycloakThe user approves the permissions the app requests
4. CallbackKeycloak to browserKeycloak redirects back with an authorization code
5. Token exchangeApp to KeycloakThe app exchanges the code for access, refresh, and ID tokens
6. AccessApp to resource serverThe app uses the access token to call the API

1. Authorization Request

The application redirects the user's browser to Keycloak's authorization endpoint with several required parameters:

Authorization request
http://localhost:8080/realms/belajar/protocol/openid-connect/auth?client_id=portal-app&redirect_uri=http://localhost:3000/callback&response_type=code&scope=openid&state=acak-1234

The response_type=code parameter signals that the client wants the authorization code flow, client_id names the application, redirect_uri is where Keycloak redirects back, and state is a random value for CSRF protection that must be verified on callback.

Keycloak displays the login page. After the credentials are correct, if the application requests certain scopes, the user sees a consent page explaining the requested permissions. This user approval is the essence of delegated authorization.

3. Callback with the Authorization Code

After a successful login, Keycloak redirects the browser back to redirect_uri, inserting code and state into the query string. The application must verify state before continuing. This code has a very short lifetime and can only be used once.

Important

Always verify the state parameter when the callback arrives before processing the code. Without this verification, your application is vulnerable to CSRF attacks that can hijack the login session.

4. Token Exchange

The application — not the browser — exchanges the code at the token endpoint:

Exchanging the code for tokens
curl -X POST "http://localhost:8080/realms/belajar/protocol/openid-connect/token" \
  -d "grant_type=authorization_code" \
  -d "client_id=portal-app" \
  -d "client_secret=rahasia-aplikasi" \
  -d "code=KODE_DARI_CALLBACK" \
  -d "redirect_uri=http://localhost:3000/callback"

The response contains the access token, refresh token, and ID token all at once. The access token is used to call the resource server, the ID token provides the user's identity information, and the refresh token gets a new access token.

The PKCE Extension

PKCE (Proof Key for Code Exchange) protects the authorization code from misuse, especially on SPAs and mobile apps that can't store a secret. The principle: the application proves that the code being sent is really its own.

  • Code verifier — a random string the application generates before starting the flow.
  • Code challenge — a derivation of the verifier sent to the authorization endpoint; the S256 method computes a SHA-256 hash, while the plain method sends the verifier as-is.
  • Proof — when exchanging the code, the application sends the verifier; Keycloak recomputes the challenge and matches it against the one stored at the start.

The PKCE steps in the Authorization Code flow:

StageValue Sent
Start of flowcode_challenge and code_challenge_method
Token exchangecode_verifier
VerificationKeycloak matches the challenge derived from the verifier

Because mobile apps and SPAs don't have a secure client_secret, PKCE takes over the client identity-proofing role. Even though server-side apps may still use a secret, best practice now recommends PKCE everywhere.

Implementing in Keycloak

To enable this flow in Keycloak:

  1. Create a client in your realm. Choose the Access Type that fits: confidential if the app can store a secret, public if it can't (SPA and mobile).
  2. Set redirect URIs — register valid redirect_uri values explicitly. Never use a loose wildcard.
  3. For public clients, enable PKCE by choosing S256 as the challenge method.
  4. Integrate a sample app — use the official OIDC library for your language rather than writing from scratch.
  5. Test the flow — run the app, log in, then inspect the received tokens. Tools like Postman or browser extensions help you see the full flow.

Best Practices

Four best practices that keep this flow safe:

  • Always use PKCE — even for server-side apps, as defense in depth.
  • Secure the redirect URIs — explicit registration, strict validation, avoid wildcards.
  • Short-lived authorization codes — codes must expire quickly and be single-use.
  • Token rotation — rotate refresh tokens so a stolen token can't be reused repeatedly.

Closing

Episode 5 broke down the Authorization Code flow: the authorization request to the /realms/{realm}/protocol/openid-connect/auth endpoint, user login and consent, the callback carrying the code, exchanging the code for access, refresh, and ID tokens at the token endpoint, and the PKCE extension that keeps this flow safe for SPAs and mobile.

Key takeaways:

  • The password never touches the application — that's this flow's core strength.
  • State must be verified — it protects against CSRF attacks.
  • PKCE completes the security — especially for public clients without a secret.
  • Client and redirect URI configuration determine security — configure carefully in the admin console.

In the next episode (episode 6), we cover the Client Credentials flow — how backend services communicate with each other without a user, complete with service accounts and their best practices.

Learn Keycloak - Authorization Code Flow | Learn SSO with Keycloak