Authorization Code and PKCE
Every user-authorizing client must use Authorization Code + PKCE with S256. Confidential clients must use PKCE as well.
1. Generate request values
code_verifier: a random string of 43 to 128 allowed characters;code_challenge: unpaddedBASE64URL(SHA256(code_verifier));state: prevents CSRF and correlates the request;nonce: required when requestingopenidand used to validate the ID Token.
Keep code_verifier, state, and nonce in the initiating session.
2. Open the authorization page
{AUTHORIZATION_ENDPOINT}
?response_type=code
&client_id={CLIENT_ID}
&redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
&scope=openid%20profile
&state={RANDOM_STATE}
&nonce={RANDOM_NONCE}
&code_challenge={S256_CHALLENGE}
&code_challenge_method=S256After sign-in, the user reviews the application, scopes, and redirect URI. Approval returns code and the original state; denial returns error=access_denied.
Validate state before using the code. An authorization code expires after five minutes and is single-use.
3. Exchange the code
curl -X POST "{TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id={CLIENT_ID}" \
--data-urlencode "code={AUTHORIZATION_CODE}" \
--data-urlencode "code_verifier={CODE_VERIFIER}" \
--data-urlencode "redirect_uri=https://app.example.com/oauth/callback"A confidential client also sends client_secret={CLIENT_SECRET}. A successful response contains access_token, refresh_token, id_token, token_type, expires_in, and the granted scope.
4. Read user information
curl "{USERINFO_ENDPOINT}" \
-H "Authorization: Bearer {ACCESS_TOKEN}"openid supplies a stable pairwise sub. With profile, the response also includes the basic profile fields the platform permits. Link local accounts by sub, not by username.
5. Refresh tokens
curl -X POST "{TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id={CLIENT_ID}" \
--data-urlencode "refresh_token={REFRESH_TOKEN}"Confidential clients also send their secret. A refresh token is consumed and replaced with a new token set. Atomically store the new values and do not refresh the same token concurrently.
Errors
OAuth errors have the following shape:
{
"error": "invalid_grant",
"error_description": "..."
}Common errors include invalid_request, invalid_client, invalid_grant, invalid_scope, access_denied, invalid_token, and insufficient_scope. Never log complete tokens, secrets, or authorization codes.
Email claims
Request openid email (or openid profile email) after the client has been approved for email. GET {USERINFO_ENDPOINT} returns email and the boolean email_verified only when the user granted email and the account has an email address. Both fields are omitted otherwise. An unverified email returns email_verified: false. profile alone never exposes email. Use sub for account linkage; email can change. These claims are returned by UserInfo, not the ID Token. See the OpenID Connect scope definitionΒ .
Remembered consent
The consent screen offers an unchecked option to remember consent for up to 15 minutes. Administrators may shorten the limit or disable it; clients cannot set it. Reuse requires a valid current platform login, an unexpired and unrevoked grant, the same or narrower scopes, and unchanged application identity, approved scopes, callbacks and relevant merchant information. Automatic reuse never extends the interval. Each request still requires fresh state, nonce and PKCE and receives a new single-use code.
The optional authorization parameter prompt=consent forces confirmation. Other prompt values, including none, are unsupported. Without an existing platform login, the user must sign in. Sessions created before this feature may require a new login before remembering consent is offered.
Users revoke grants from Settings β Authorized applications. Administrators configure the maximum in System management β Properties β OAuth consent security policy; 0 disables reuse. Revoking a grant or changing a clientβs approved scopes invalidates existing codes, access tokens and refresh tokens, including after subsequent reauthorization.