Token endpoint - Amazon Cognito

Token endpoint

The OAuth 2.0 token endpoint at /oauth2/token issues JSON web tokens (JWTs).

Your user pool OAuth 2.0 authorization server issues JSON web tokens (JWTs) from the token endpoint to the following types of sessions:

  1. Users who have completed a request for an authorization code grant. Successful redemption of a code returns ID, access, and refresh tokens.

  2. Machine-to-machine (M2M) sessions that have completed a client-credentials grant. Successful authorization with the client secret returns an access token.

The token endpoint becomes publicly available when you add a domain to your user pool. It accepts HTTP POST requests. For application security, use PKCE with your authorization code sign-in events. PKCE verifies that the user passing an authorization code is that same user who authenticated. For more information about PKCE, see IETF RFC 7636.

You can learn more about the user pool app clients and their grant types, client secrets, authorized scopes, and client IDs at User pool app clients. You can learn more about M2M authorization, client credentials grants, and authorization with access token scopes at OAuth 2.0 scopes and API authorization with resource servers.

To retrieve information about a user from their access token, pass it to your UserInfo endpoint or to a GetUser API request.

POST /oauth2/token

The /oauth2/token endpoint only supports HTTPS POST. Your app makes requests to this endpoint directly, not through the user's browser.

The token endpoint supports client_secret_basic and client_secret_post authentication. For more information about the OpenID Connect specification, see Client Authentication. For more information about the token endpoint from the OpenID Connect specification, see Token Endpoint.

Request parameters in header

Authorization

If the client was issued a secret, the client can pass its client_id and client_secret in the authorization header as client_secret_basic HTTP authorization. You can also include the client_id and client_secret in the request body as client_secret_post authorization.

The authorization header string is Basic Base64Encode(client_id:client_secret). The following example is an authorization header for app client djc98u3jiedmi283eu928 with client secret abcdef01234567890, using the Base64-encoded version of the string djc98u3jiedmi283eu928:abcdef01234567890:

Authorization: Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw
Content-Type

Set the value of this parameter to 'application/x-www-form-urlencoded'.

Request parameters in body

grant_type

(Required) The type of OIDC grant that you want to request.

Must be authorization_code or refresh_token or client_credentials. You can request an access token for a custom scope from the token endpoint under the following conditions:

  • You enabled the requested scope in your app client configuration.

  • You configured your app client with a client secret.

  • You enable client credentials grant in your app client.

client_id

(Optional) The ID of an app client in your user pool. Specify the same app client that authenticated your user.

You must provide this parameter if the client is public and does not have a secret, or with client_secret in client_secret_post authorization.

client_secret

(Optional) The client secret for the app client that authenticated your user. Required if your app client has a client secret and you did not send an Authorization header.

scope

(Optional) Can be a combination of any custom scopes that are associated with an app client. Any scope that you request must be activated for the app client. If not, Amazon Cognito will ignore it. If the client doesn't request any scopes, the authentication server assigns all custom scopes that you authorized in your app client configuration.

Only used if the grant_type is client_credentials.

redirect_uri

(Optional) Must be the same redirect_uri that was used to get authorization_code in /oauth2/authorize.

You must provide this parameter if grant_type is authorization_code.

refresh_token

(Optional) To generate new access and ID tokens for a user's session, set the value of a refresh_token parameter in your /oauth2/token request to a previously issued refresh token from the same app client.

code

(Optional) The authorization code from an authorization code grant. You must provide this parameter if your authorization request included a grant_type of authorization_code.

code_verifier

(Optional) The arbitrary value that you used to calculate the code_challenge in an authorization code grant request with PKCE.

Example requests with positive responses

Exchanging an authorization code for tokens

Example – POST request

POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token& Content-Type='application/x-www-form-urlencoded'& Authorization=Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw grant_type=authorization_code& client_id=1example23456789& code=AUTHORIZATION_CODE& redirect_uri=com.myclientapp://myclient/redirect

Example – response

HTTP/1.1 200 OK Content-Type: application/json { "access_token":"eyJra1example", "id_token":"eyJra2example", "refresh_token":"eyJj3example", "token_type":"Bearer", "expires_in":3600 }
Note

The token endpoint returns refresh_token only when the grant_type is authorization_code.

Exchanging client credentials for an access token: client secret in authorization header

Example – POST request

POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token > Content-Type='application/x-www-form-urlencoded'& Authorization=Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw grant_type=client_credentials& client_id=1example23456789& scope=resourceServerIdentifier1/scope1 resourceServerIdentifier2/scope2

Example – response

HTTP/1.1 200 OK Content-Type: application/json { "access_token":"eyJra1example", "token_type":"Bearer", "expires_in":3600 }

Exchanging client credentials for an access token: client secret in request body

Example – POST request

POST /oauth2/token HTTP/1.1 Content-Type: application/x-www-form-urlencoded X-Amz-Target: AWSCognitoIdentityProviderService.Client credentials request User-Agent: USER_AGENT Accept: / Accept-Encoding: gzip, deflate, br Content-Length: 177 Referer: http://auth.example.com/oauth2/token Host: auth.example.com Connection: keep-alive grant_type=client_credentials&client_id=1example23456789&scope=my_resource_server_identifier%2Fmy_custom_scope&client_secret=9example87654321

Example – response

HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Date: Tue, 05 Dec 2023 16:11:11 GMT x-amz-cognito-request-id: 829f4fe2-a1ee-476e-b834-5cd85c03373b { "access_token": "eyJra12345EXAMPLE", "expires_in": 3600, "token_type": "Bearer" }

Exchanging an authorization code grant with PKCE for tokens

Example – POST request

POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token Content-Type='application/x-www-form-urlencoded'& Authorization=Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw grant_type=authorization_code& client_id=1example23456789& code=AUTHORIZATION_CODE& code_verifier=CODE_VERIFIER& redirect_uri=com.myclientapp://myclient/redirect

Example – response

HTTP/1.1 200 OK Content-Type: application/json { "access_token":"eyJra1example", "id_token":"eyJra2example", "refresh_token":"eyJj3example", "token_type":"Bearer", "expires_in":3600 }
Note

The token endpoint returns refresh_token only when the grant_type is authorization_code.

Exchanging a refresh token for tokens

Example – POST request

POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token > Content-Type='application/x-www-form-urlencoded'& Authorization=Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw grant_type=refresh_token& client_id=1example23456789& refresh_token=eyJj3example

Example – response

HTTP/1.1 200 OK Content-Type: application/json { "access_token":"eyJra1example", "id_token":"eyJra2example", "token_type":"Bearer", "expires_in":3600 }
Note

The token endpoint returns refresh_token only when the grant_type is authorization_code.

Examples of negative responses

Example – error response

HTTP/1.1 400 Bad Request Content-Type: application/json;charset=UTF-8 { "error":"invalid_request|invalid_client|invalid_grant|unauthorized_client|unsupported_grant_type" }
invalid_request

The request is missing a required parameter, includes an unsupported parameter value (other than unsupported_grant_type), or is otherwise malformed. For example, grant_type is refresh_token but refresh_token is not included.

invalid_client

Client authentication failed. For example, when the client includes client_id and client_secret in the authorization header, but there's no such client with that client_id and client_secret.

invalid_grant

Refresh token has been revoked.

Authorization code has been consumed already or does not exist.

App client doesn't have read access to all attributes in the requested scope. For example, your app requests the email scope and your app client can read the email attribute, but not email_verified.

unauthorized_client

Client is not allowed for code grant flow or for refreshing tokens.

unsupported_grant_type

Returned if grant_type is anything other than authorization_code or refresh_token or client_credentials.