Authorization Code grant + PKCE (on behalf of a user)

Use the Authorization Code grant when acting on behalf of an authenticated user — for example, creating an Experience Connection on their Alianza account.

PKCE (RFC 7636) is required. It binds the token exchange to the original authorization request, preventing authorization-code interception attacks.

For each authorization request:

  1. Generate a random code_verifier (43–128 unreserved characters).
  2. Derive code_challenge = BASE64URL-ENCODE(SHA256(code_verifier)).
  3. Send the code_challenge on the authorize request; send the code_verifier on the token exchange.

Required scopes: experience-connections:manage, experience-assignments:manage.

Step 1 — Redirect to Authorize

GET {baseAuthUrl}/authorize
  ?response_type=code
  &client_id={client_id}
  &redirect_uri=https://your-app.example.com/callback
  &scope=experience-connections:manage experience-assignments:manage offline_access
  &state={random_state}
  &code_challenge={code_challenge}
  &code_challenge_method=S256

The Alianza auth server authenticates the user and presents a consent screen. Users who have already consented in a prior session are redirected without interaction.

Step 1b — Handle the callback

After authentication, Alianza redirects to your redirect_uri with two query parameters:

  • code — short-lived authorization code, exchange this for a token.
  • state — the same value you sent in step 1. Verify it matches to prevent CSRF attacks.
GET https://your-app.example.com/callback
    ?code=SplxlOBeZQQYbYS6WxSbIA
    &state={random_state}

If the returned state does not match the value you stored before redirecting, reject the request — it may be a CSRF attack.

Step 2 — Exchange code for token

POST {baseAuthUrl}/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code={authorization_code}
&redirect_uri=https://your-app.example.com/callback
&client_id={client_id}
&code_verifier={code_verifier}

Include the client_secret parameter only if you are acting as a confidential client. Public clients omit it.

Token caching

Access tokens are valid for expires_in seconds. Cache them and refresh before expiry.

See also