Token: swap a code
Swaps the code from the redirect for an ID token, an access token and, with offline_access, a refresh token.
Melden Sie sich an, um Ihre eigene Test-Client-ID in den Beispielen zu sehen.
POST https://accounts.aton-network.org/oauth/token
When to use it
On your server, in the route your redirect address points at, straight after checking state.
Authentication
client_secret_basic (preferred), client_secret_post, private_key_jwt, or none for a public app. See Secrets and certificates.
Parameters
| Name | In | Type | Required | Limits | What it is |
|---|---|---|---|---|---|
grant_type | form | string | yes | authorization_code | This grant. |
code | form | string | yes | The code from the redirect. 60 seconds, once. | |
redirect_uri | form | string | yes | The same redirect address the authorize request used. | |
code_verifier | form | string | yes | 43 to 128 characters | The verifier whose challenge you sent to authorize. |
client_id | form | string | no | Required for a public app, and with client_secret_post. | |
client_secret | form | string | no | Only with client_secret_post. Prefer HTTP Basic. | |
client_assertion_type | form | string | no | urn:ietf:params:oauth:client-assertion-type:jwt-bearer | With private_key_jwt. |
client_assertion | form | string | no | A JWT signed with your certificate's private key: iss and sub your client ID, aud the token endpoint, exp at most ten minutes ahead, a jti used once. |
Request
# Swap the code from the redirect for tokens, on your server. HTTP Basic carries your client ID and
# secret; the verifier proves this is the browser that started the sign-in.
curl https://accounts.aton-network.org/oauth/token \
-u "$ATHERON_CLIENT_ID:$ATHERON_CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code="$CODE" \
-d redirect_uri=https://app.example.com/callback \
-d code_verifier="$VERIFIER"Response
http
HTTP 200
content-type: application/json
cache-control: no-store
{
"access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "openid profile email offline_access",
"id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjYtMTAtMDEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmF0b24tbmV0d29yay5vcmciLCJzdWIiOiI5YTZk...",
"refresh_token": "ath_rt_6Qm9..."
}Errors
| HTTP | error | Cause | Fix |
|---|---|---|---|
| 400 | invalid_request | A parameter is missing or malformed: no PKCE, PKCE with plain, a bad max_age, prompt=none combined with another prompt, or a token request that is not form encoded. | Send every required parameter once, PKCE with S256, and form-encode the token request. |
| 401 | invalid_client | Your app could not be authenticated: a wrong or expired secret, a revoked or expired certificate, a bad client_assertion (aud must be the token endpoint, exp at most ten minutes ahead, jti new), a public app sending a secret, or the app is suspended. | Check the credential on the app's Credentials page and its expiry. Rotate without downtime: add a new one, deploy, then revoke the old. |
| 400 | invalid_grant | The code or refresh token cannot be used: the code expired (60 seconds) or was used, it was issued to another client, the redirect_uri or code_verifier does not match, a refresh token was used twice, access was withdrawn, or the tester was removed. | Start the sign-in again. Swap each code once, straight away, with the same redirect_uri and the verifier you kept. |
| 400 | unsupported_grant_type | grant_type is not authorization_code or refresh_token. | Use one of the two. |
| 429 | rate_limited | Over your quota for this bucket, this minute or this day. | Wait the Retry-After seconds. Requests over the limit still count, so a retry loop keeps you over it. |
Good to know
- The body must be application/x-www-form-urlencoded. JSON is refused with invalid_request.
- Check the ID token before you trust it: signature (ES256, from the keys), iss, aud is your client ID, exp, and nonce.
- A refresh token comes back only when you asked for offline_access and the person agreed.
Security
- Never call this from a browser with a secret. A public app sends client_id and its PKCE verifier only.
- Send an assertion or a secret, never both.
Try it
Fragen Sie Atlas
KI-AssistentFragen Sie alles zu Mit Atheron anmelden, zur API oder zum Portal. Die Antwort kommt aus unserer Dokumentation, mit Links zu den genutzten Seiten.