The following sections outline the main components required to implement the Authorization Code with PKCE flow using direct calls to the OIDC & OAuth 2.0 API (opens new window). Typically, you don't need to make direct calls if you're using one of the Okta SDKs.
Create the Proof Key for Code Exchange
Similar to the standard Authorization Code flow, your app starts by redirecting the user's browser to your authorization server's /authorize
endpoint. However, in this instance you also have to pass along a code challenge.
Your first step is to add code to your app that generates a code verifier and challenge:
- Code verifier: A random URL-safe string with a minimum length of 43 characters
- Code challenge: A Base64-encoded SHA-256 hash of the code verifier
The PKCE generator code returns both values as JSON:
The code_challenge
is a Base64-encoded SHA256 hash of the code_verifier
. Your app saves the code_verifier
for later, and sends the code_challenge
along with the authorization request to your authorization server's /authorize
URL.
Request an authorization code
If you're using the org authorization server, then your request URL would look something like this:
Note the parameters that are being passed:
client_id
: The client ID of the app integration that you created earlier. Find it in the Admin Console on your app integration's General tab. response_type=code
: Indicates that you're using the Authorization Code grant type scope=openid
: The /token
endpoint returns an ID token. For custom scopes, see the Create Scopes section of the Create an authorization server guide. redirect_uri
: The callback location where the user agent is directed to along with the code
. This URI must match one of the Sign-in redirect URIs that you specified when you created your app integration earlier. state
: An arbitrary alphanumeric string that the authorization server reproduces when redirecting the user agent back to the client. This is used to help prevent cross-site request forgery. code_challenge_method
: The hash method used to generate the challenge, which is always S256
code_challenge
: The code challenge used for PKCE
See the OAuth 2.0 API reference (opens new window) for more information on these parameters.
If the user doesn't have an existing session, this request opens the Okta sign-in page. If they have an existing session, or after they authenticate, the user arrives at the specified redirect_uri
along with an authorization code
:
This code can only be used once, and remains valid for 300 seconds, during which time it can be exchanged for tokens.
Exchange the code for tokens
To exchange the authorization code for access and ID tokens, you pass it to your authorization server's /token
endpoint along with the code_verifier
that was generated at the beginning:
Important: Unlike the regular Authorization Code flow, this call doesn't require the HTTP Authorization header with the client ID and secret. That is why this version of the Authorization Code flow is appropriate for mobile apps.
Note the parameters that are being passed:
grant_type=authorization_code
: Indicates that you're using the Authorization Code grant type redirect_uri
: The URI that was used to get the authorization code code
: The authorization code that you got from the /authorize
endpoint code_verifier
: The PKCE code verifier that your app generated at the beginning of this flow client_id
: The client ID of the app integration that you created earlier
See the OIDC & OAuth 2.0 API reference (opens new window) for more information on these parameters.
If the code is still valid, and the code verifier matches, your application receives back access and ID tokens:
Validate access token
When your application passes a request with an access token, the resource server needs to validate it. See Validate access tokens.