The authorization code flow, hop by hop
Follow a browser through redirect, code and token exchange, and see what PKCE actually protects.
Open this lesson in the learning hubKey points
- Hitting a protected page redirects the browser to the provider with
response_type=codeand a randomstate. - The password is typed at the provider, never at your app. That is the entire reason the redirect exists.
- The provider redirects back to
/login/oauth2/code/{registrationId}with a short-lived, single-use code. - Your server then swaps that code for tokens over the back channel, so no token ever appears in the URL bar.
- PKCE sends a hash up front and the original secret at exchange time, which makes a stolen code useless on its own.
stateis the CSRF defence for the redirect itself: a callback carrying the wrong state is dropped.
Example
# 1. GET /oauth2/authorization/google -> 302 to the provider (+ state, + PKCE challenge)
# 2. provider sends the browser back to /login/oauth2/code/google?code=...&state=...
# 3. your server posts the code + verifier to the token endpoint, back channel only
spring:
security:
oauth2:
client:
registration:
google:
client-id: set-from-an-environment-variable
client-secret: set-from-an-environment-variable
scope: openid, profile, email
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
google:
issuer-uri: https://accounts.google.com
# in the chain: http.oauth2Login(Customizer.withDefaults());
The browser carries a code, never a token, and PKCE makes a stolen code worthless.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Security course, and every lesson in it is listed on the Spring Security contents page.