PKCE
Proof Key for Code Exchange (PKCE, RFC 7636) is an extension to the OAuth 2.0 Authorization Code Flow that prevents authorization code interception attacks. PKCE is required by OAuth 2.1 guidance and is strongly recommended for all clients, especially mobile and single-page applications.
PKCE can be used with or without a client secret. Mobile and other public clients can safely perform the flow without a client secret because PKCE ensures only the app instance that initiated the request can complete the token exchange.
How PKCE works
PKCE adds a dynamically created cryptographic secret to the standard authorization code flow. Before each authorization request, your application generates a random code_verifier and derives a code_challenge from it. The challenge is sent with the authorization request, and the original verifier is sent with the token exchange, allowing ID.me to verify both came from the same client.
Prerequisites
Before implementing PKCE, ensure you have:
- A registered ID.me application with a
client_id - One or more configured
redirect_urivalues - Access to the appropriate environment (Sandbox or Production)
Tip
Most OAuth/OIDC client libraries handle PKCE automatically. Check your library’s documentation before implementing the steps below manually.
Step-by-step implementation
Generate PKCE pair
Generate a random code_verifier — a 43–128 character URL-safe string. Then derive the code_challenge by computing the SHA-256 hash of the verifier and Base64-URL encoding the result without padding. Store the code_verifier securely for use during the token exchange in step 6.
Send authorization request
Redirect the user to the ID.me authorization endpoint. Include the standard OIDC parameters along with the two PKCE-specific parameters.
Parameters
User verifies identity
The user is redirected to ID.me to authenticate and complete identity verification. No action is required from your application during this step.
Receive authorization code
ID.me redirects the user back to your redirect_uri with an authorization code and the state value appended as query parameters.
Critical
Always verify that the returned state matches the value you sent in the authorization request before proceeding. This prevents CSRF attacks.
Exchange code for tokens
Send a POST request to ID.me’s token endpoint with the code_verifier to complete the exchange. ID.me verifies that the code_verifier matches the code_challenge sent in step 3, confirming the request originated from the same client.
- Endpoint:
https://api.id.me/oauth/token - Method:
POST - Content-Type:
application/x-www-form-urlencoded
Parameters
The response includes an access_token, refresh_token, and an id_token (a signed JWT containing user claims).
Get user attributes
Send a GET request to the UserInfo endpoint with the access token to retrieve user attributes.
- Endpoint:
https://api.id.me/api/public/v3/userinfo - Method:
GET - Authorization:
Bearer {access_token}
For details on validating and decoding the ID token, see Integration.
PKCE for mobile applications
PKCE is especially important for mobile clients where the client secret cannot be stored securely. Because PKCE ensures that only the same app instance that initiated the login request can complete the token exchange — even if the authorization code is intercepted — mobile and other public clients can safely perform the flow without a client secret.
For mobile-specific implementation details, see the Mobile SDK documentation.
When using PKCE without a client secret, omit the client_secret parameter from the token exchange request. The code_verifier provides the necessary proof of identity.