OAuth 2.0 / OpenID Connect Flow

Table of Contents

  1. The Authorization Code Flow, Step by Step
  2. Why the App Never Sees the Password
  3. Why HTTPS Matters
  4. Token Expiration
  5. Client Credentials Flow
  6. Which Flow, When
  7. Beginner Pitfalls

This is the most important concept in the whole crash course — everything in Part 6 and Part 7 is downstream of understanding this flow.

1. The Authorization Code Flow, Step by Step

Six-step sequence: User logs into the Application, which redirects to Keycloak, the user authenticates, and tokens flow back through an authorization code

  1. Login — the user clicks "Log in" in the application
  2. Redirect — the application redirects the browser to Keycloak, including its client ID and a redirect URI (from Part 4)
  3. Login form — Keycloak shows its own login page and authenticates the user directly — the application is not involved in this step at all
  4. Authorization code — Keycloak redirects the browser back to the application's redirect URI, with a short-lived, single-use authorization code attached
  5. Exchange code — the application sends that code to Keycloak's token endpoint, server-to-server, to exchange it for tokens
  6. Tokens — Keycloak returns the access token, refresh token, and ID token from Part 2

2. Why the App Never Sees the Password

Step 3 happens entirely on Keycloak's own login page, inside the user's browser — the application's code is never handed the username or password, only redirected away and later handed back a code. This is the entire point of the flow: the application proves it can reach Keycloak's token endpoint, without ever touching the user's credentials.

3. Why HTTPS Matters

The authorization code (step 4) and the tokens (step 6) both travel through the browser's redirect chain and network requests. Without HTTPS, a code or token in transit is plaintext — anyone on the network path can read and reuse it. start-dev mode (from Part 3) relaxes this for local development only; a real deployment must run behind HTTPS.

4. Token Expiration

Access tokens are deliberately short-lived (Keycloak's default is 5 minutes) — if one leaks, the exposure window is small. The refresh token (longer-lived) lets the application silently get a new access token without forcing the user to log in again. This is why Part 2 separates the two: one is handed to every API call, the other is only ever sent back to Keycloak.

5. Client Credentials Flow

Not every caller is a human. The Client Credentials flow skips the user entirely — a client authenticates with its own client ID and secret directly against the token endpoint and gets back an access token representing the application itself, not a user.

curl -X POST http://localhost:8080/realms/crash-course/protocol/openid-connect/token \
  -d grant_type=client_credentials \
  -d client_id=<confidential-client-id> \
  -d client_secret=<client-secret>

This needs a confidential client (see Part 2) — a public client has no secret to authenticate with.

6. Which Flow, When

FlowWho's involvedUse case
Authorization CodeA human user, in a browserFrontends, mobile apps — anywhere a person logs in
Client CredentialsNo human — service to serviceBackend job talking to another backend API

Part 7's demo uses a third option — the password grant — purely as a curl-friendly shortcut to get a real token without standing up a frontend; it is explained there as a demo convenience, not a flow to use in production.

7. Beginner Pitfalls

  • Thinking the access token comes back in step 4. Step 4 only returns a code — the code is exchanged for tokens separately in step 5/6. Confusing the two is the most common source of confusion with this flow.
  • Reusing an authorization code. It's single-use by design — Keycloak rejects a second exchange attempt with the same code.
  • Trying Client Credentials with a public client. It has no secret, so there's nothing to authenticate the request with — Keycloak will reject it.

Official docs:

Buy Me a Coffee

Found this tutorial helpful? Consider buying me a coffee to support more free content!