Contents

POST /token#

This is the token endpoint of the OAuth 2.0 specification. This endpoint is used by the client to provide its authorization code, demonstrating that it has the right to learn a particular user’s validated address. In return, the challenger service returns the access token. Renewal is not supported.

Request:

The request must include an application/x-www-form-urlencoded body (multipart/form-data is accepted as well) specifying the client_id, redirect_uri, client_secret, code and grant_type. The grant_type must be set to authorization_code. The redirect_uri must match the URI from /authorize. The code must be the authorization code that /solve returned to the user. The client_id and client_secret must match the usual client credentials. Since protocol v3, code_verifier can also be included.

The request body is limited to 2048 bytes, as is each individual field. Note that the client credentials must be passed in the body (client_secret_post); HTTP Basic authentication (client_secret_basic) is not supported.

Response:

Error responses follow RFC 6749, section 5.2 with an “error” field in JSON, as well as also returning GNU Taler style error messages. The error values used are invalid_request, unsupported_grant_type, invalid_client, invalid_grant and server_error. Since protocol v8 every error response of this endpoint carries the error field, including 415, 413 and 500.

200 OK:

The body will be a ChallengerAuthResponse.

400 Bad Request:

A required POST field (grant_type, client_id, client_secret, code or redirect_uri) is missing or malformed, grant_type is not authorization_code, or the authorization code was not accepted. Error codes used are:

  • TALER_EC_GENERIC_PARAMETER_MISSING (error is invalid_request, or invalid_grant for a missing code_verifier) — a required field is absent; detail names it.

  • TALER_EC_GENERIC_PARAMETER_MALFORMED (error is invalid_request, or unsupported_grant_type when the grant_type is not authorization_code) — the Content-Length header is not a number, client_id is not a number, or the code_verifier violates the length (43–128) or character-set rules of RFC 7636.

  • TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE (error is invalid_grant) — the code is not well-formed, does not correspond to a solved validation of this client, does not match its recomputed authentication tag, or the code_verifier does not match the stored code_challenge.

  • TALER_EC_CHALLENGER_GRANT_UNKNOWN (error is invalid_grant) — the authorization code was already redeemed, or the validation expired between the two database transactions.

Note

Several of these conditions are answered with a byte-identical response on purpose, so that a caller cannot use /token as an oracle to distinguish “this nonce does not exist” from “this validation has no address” from “your authentication tag is wrong”.

401 Unauthorized:

Authentication of the client failed (per RFC 6749, section 5.2): either the client_id/client_secret pair is invalid, or the redirect_uri does not match the one registered with the client. Error codes used are:

  • TALER_EC_CHALLENGER_CLIENT_AUTHENTICATION_FAILED — the client_id/client_secret pair does not match a registered client. Since protocol v8; previously TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN, which is now used only by /setup/$CLIENT_ID with a 404 so that each error code maps to exactly one HTTP status.

  • TALER_EC_CHALLENGER_GENERIC_CLIENT_FORBIDDEN_BAD_REDIRECT_URI

Both are returned with error set to invalid_client and a WWW-Authenticate: Bearer error="invalid_client" header. Note that failures concerning the code itself — including PKCE code_verifier mismatches, which exist since protocol v3 — are reported with 400, not 401.

405 Method Not Allowed:

The request used a method other than POST or OPTIONS. Returned by the request router with an Allow header and an empty body; in particular there is no Taler error code.

409 Conflict:

A code was presented for a validation process for which the user has not (yet) submitted any address, so the token cannot be issued. Returned with TALER_EC_CHALLENGER_MISSING_ADDRESS. Removed in v8 (to better match RFC 6749, section 5.2); the condition is now reported as 400 with TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE.

413 Request entity too large:

The request body exceeds the 2048 byte limit. Returned with TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT and error set to invalid_request.

415 Unsupported Media Type:

The Content-Type is missing or is not one the service can parse. Returned with TALER_EC_GENERIC_PARAMETER_MALFORMED, detail set to "Content-Type" and error set to invalid_request. Since protocol v8; previously reported as 400.

500 Internal Server Error:

The challenger service encountered an internal error, for example a database failure or a failure of the SHA-256 or Base64 helpers used for PKCE verification. Error codes used are:

  • TALER_EC_GENERIC_DB_FETCH_FAILEDdetail is "get_client" or "get_validation_pkce".

  • TALER_EC_GENERIC_DB_STORE_FAILEDdetail is "do_insert_token".

  • TALER_EC_GENERIC_DB_SOFT_FAILURE — a serialization failure that survived all retries.

  • TALER_EC_GENERIC_DB_INVARIANT_FAILURE (error is server_error) — the stored validation has a code_challenge but no challenge method.

  • TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE (error is server_error) — the SHA-256 or Base64 helper used for PKCE verification failed.

All of these carry error set to server_error. Note that the stored code_challenge_method being unknown is reported with TALER_EC_GENERIC_DB_INVARIANT_FAILURE since protocol v8; it previously used TALER_EC_GENERIC_PARAMETER_MALFORMED, which wrongly suggested the client’s request was at fault.

Details::

interface ChallengerAuthResponse {
  // Token used to authenticate access in /info.
  access_token: string;

  // Type of the access token.
  token_type: "Bearer";

  // Amount of time that an access token is valid (in seconds).
  expires_in: Integer;

}