How do I get an access token from an authorization server?

This document shows you how to get OAuth 2.0 access tokens and authorization codes with the Apigee API. We also show how to create policies for each OAuth 2.0 grant type and configure proxy endpoints to accept client requests.

Note: These examples show the most basic configurations possible. The OAuthV2 policy includes many optional configurable elements that are not shown in this topic. For more information on those elements, see OAuthV2 policy.

Use the authorization code grant type

This section explains how to get an access token using the authorization code grant type flow. The token request for this flow requires an authorization code. See Get an authorization code. See also What are OAuth 2.0 grant types.

Note: The OAuthV2 policy configuration in this section uses the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
7 operation. This operation generates an opaque string token format. You can also generate JWT-formatted tokens by substituting the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
8 operation. See also Using JWT OAuth token operations.

Sample request

curl -i -H 'Content-Type: application/x-www-form-urlencoded' \
   -H 'Authorization: Basic c3FIOG9vSGV4VHo4QzAyg5T1JvNnJoZ3ExaVNyQWw6WjRsanRKZG5lQk9qUE1BVQ' \
   -X POST 'https://apitest.acme.com/oauth/token' \
   -d 'code=I9dMGHAN&grant_type=authorization_code&redirect_uri=http://example-callback.com' 

Required parameters

By default, these parameters must be

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
9 and specified in the request body (as shown in the sample above); however, it is possible to change this default by configuring the
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
0,
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
1, and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
2 elements in the OAuthV2 policy. See OAuthV2 policy.

  • grant_type - Must be set to the value
    oauthv2accesstoken.{policy-name}.access_token   
    oauthv2accesstoken.{policy-name}.expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token
    oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token_issued_at
    oauthv2accesstoken.{policy-name}.refresh_token_status
    
    3.
  • code - The authorization code. See Requesting an authorization code.
  • redirect_uri - You must provide this parameter if the
    oauthv2accesstoken.{policy-name}.access_token   
    oauthv2accesstoken.{policy-name}.expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token
    oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token_issued_at
    oauthv2accesstoken.{policy-name}.refresh_token_status
    
    4 parameter was included in the authorization code request. If the
    oauthv2accesstoken.{policy-name}.access_token   
    oauthv2accesstoken.{policy-name}.expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token
    oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token_issued_at
    oauthv2accesstoken.{policy-name}.refresh_token_status
    
    4 parameter was not included in the authorization code request, and if you do not provide this parameter, then this policy uses the value of the Callback URL provided in the registered developer app.

Optional parameters

  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

You must pass the Client ID and Client Secret either as a Basic Authorization header (Base64-encoded) or as form parameters

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
6 and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
7. You obtain these values from a registered developer app. See also Encoding basic authentication credentials.

Sample endpoint

Here's a sample endpoint configuration for generating an access token. It'll execute the GenerateAccessToken policy, which must be configured to support the authorization_code grant type.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...

Sample policy

This is a basic GenerateAccessToken policy that is configured to accept the

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
3 grant type. For information on optional configuration elements that you can configure with this policy, see OAuthV2 policy.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns a JSON response that includes the access token, as shown below. The
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
3 grant type creates an access token and a refresh tokens, so a response might look like this:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
Note: Yes, it's kind of unusual to specify the expiry values in milliseconds in the policy, but receive them in seconds in the response payload. We are aware.

If

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to false, the policy does not return a response. Instead, it populates the following set of flow variables with data pertaining to the access token grant.

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status

For example:

oauthv2accesstoken.GenerateAccessToken.access_token     
oauthv2accesstoken.GenerateAccessToken.expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token    
oauthv2accesstoken.GenerateAccessToken.refresh_token_expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token_issued_at  
oauthv2accesstoken.GenerateAccessToken.refresh_token_status

Use the client credentials grant type

This section explains how to get an access token using the client credentials grant type flow. See also What are OAuth 2.0 grant types.

Note: The OAuthV2 policy configuration in this section uses the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
7 operation. This operation generates an opaque string token format. You can also generate JWT-formatted tokens by substituting the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
8 operation. See also Using JWT OAuth token operations.

Sample request

curl -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: Basic c3FIOG9vSGV4VHo4QzAyg5T1JvNnJoZ3ExaVNyQWw6WjRsanRKZG5lQk9qUE1BVQ" \
  -X POST "https://apitest.acme.com/oauth/token" \
  -d "grant_type=client_credentials"

Required parameters

  • grant_type - Must be set to the value
    oauthv2accesstoken.GenerateAccessToken.access_token     
    oauthv2accesstoken.GenerateAccessToken.expires_in         
    oauthv2accesstoken.GenerateAccessToken.refresh_token    
    oauthv2accesstoken.GenerateAccessToken.refresh_token_expires_in         
    oauthv2accesstoken.GenerateAccessToken.refresh_token_issued_at  
    oauthv2accesstoken.GenerateAccessToken.refresh_token_status
    
    4.

    By default, the required

    oauthv2accesstoken.GenerateAccessToken.access_token     
    oauthv2accesstoken.GenerateAccessToken.expires_in         
    oauthv2accesstoken.GenerateAccessToken.refresh_token    
    oauthv2accesstoken.GenerateAccessToken.refresh_token_expires_in         
    oauthv2accesstoken.GenerateAccessToken.refresh_token_issued_at  
    oauthv2accesstoken.GenerateAccessToken.refresh_token_status
    
    5 parameter must be
    {
        "issued_at": "1420262924658",
        "scope": "READ",
        "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
        "refresh_token_issued_at": "1420262924658",
        "status": "approved",
        "refresh_token_status": "approved",
        "api_product_list": "[PremiumWeatherAPI]",
        "expires_in": "1799", //--in seconds
        "developer.email": "[email protected]",
        "organization_id": "0",
        "token_type": "BearerToken",
        "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
        "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
        "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
        "organization_name": "docs",
        "refresh_token_expires_in": "86399", //--in seconds
        "refresh_count": "0"
    }
    
    9 and specified in the request body (as shown in the sample above); however, it is possible to change this default by configuring the
    oauthv2accesstoken.{policy-name}.access_token   
    oauthv2accesstoken.{policy-name}.expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token
    oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
    oauthv2accesstoken.{policy-name}.refresh_token_issued_at
    oauthv2accesstoken.{policy-name}.refresh_token_status
    
    0 element in the OAuthV2 policy. For example, you could elect to pass the parameter in a query parameter. For details, see OAuthV2 policy.

Optional parameters

  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

You must pass the Client ID and Client Secret either as a Basic Authorization header (Base64-encoded) or as form parameters

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
6 and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
7. You obtain these values from the registered developer app associated with the request. See also Encoding basic authentication credentials.

Sample endpoint

Here's a sample endpoint configuration for generating an access token. It'll execute the GenerateAccessToken policy, which must be configured to support the client_credentials grant type.

...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...

Sample policy

This is a basic GenerateAccessToken policy that is configured to accept the

oauthv2accesstoken.GenerateAccessToken.access_token     
oauthv2accesstoken.GenerateAccessToken.expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token    
oauthv2accesstoken.GenerateAccessToken.refresh_token_expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token_issued_at  
oauthv2accesstoken.GenerateAccessToken.refresh_token_status
4 grant type. For information on optional configuration elements that you can configure with this policy, see OAuthV2 policy.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn> <!-- 30 minutes -->
    <SupportedGrantTypes>
      <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns a JSON response. Note that with the
oauthv2accesstoken.GenerateAccessToken.access_token     
oauthv2accesstoken.GenerateAccessToken.expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token    
oauthv2accesstoken.GenerateAccessToken.refresh_token_expires_in         
oauthv2accesstoken.GenerateAccessToken.refresh_token_issued_at  
oauthv2accesstoken.GenerateAccessToken.refresh_token_status
4 grant type, refresh tokens are not supported. Only an access token is minted. For example:

{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}

If

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to false, the policy does not return a response. Instead, it populates the following set of flow variables with data pertaining to the access token grant.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
0

For example:

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
1

Use the password grant type

This section explains how to get an access token using the resource owner password credentials (password) grant type flow. See also Implementing the password grant type. See also What are OAuth 2.0 grant types.

Note: The OAuthV2 policy configuration in this section uses the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
7 operation. This operation generates an opaque string token format. You can also generate JWT-formatted tokens by substituting the
{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
8 operation. See also Using JWT OAuth token operations.

Sample request

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
2

Required parameters

By default, these parameters must be

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
9 and specified in the request body (as shown in the sample above); however, it is possible to change this default by configuring the
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
0,
curl -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: Basic c3FIOG9vSGV4VHo4QzAyg5T1JvNnJoZ3ExaVNyQWw6WjRsanRKZG5lQk9qUE1BVQ" \
  -X POST "https://apitest.acme.com/oauth/token" \
  -d "grant_type=client_credentials"
8, and
curl -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: Basic c3FIOG9vSGV4VHo4QzAyg5T1JvNnJoZ3ExaVNyQWw6WjRsanRKZG5lQk9qUE1BVQ" \
  -X POST "https://apitest.acme.com/oauth/token" \
  -d "grant_type=client_credentials"
9 elements in the OAuthV2 policy. See OAuthV2 policy.

User credentials are typically validated against a credential store using an LDAP or JavaScript policy.

  • grant_type - Must be set to the value
    ...   
           <Flow name="generate-access-token">
                <Request>
                    <Step>
                        <Name>GenerateAccessToken</Name>
                    </Step>
                </Request>
                <Response/>
                <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
            </Flow>
    ...
    
    0.
  • username - The resource owner's user name.
  • password - The resource owner's password.

Optional parameters

  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

You must pass the Client ID and Client Secret either as a Basic Authorization header (Base64-encoded) or as form parameters

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
6 and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
7. You obtain these values from the registered developer app associated with the request. See also Encoding basic authentication credentials.

Sample endpoint

Here's a sample endpoint configuration for generating an access token. It'll execute the GenerateAccessToken policy, which must be configured to support the password grant type.

...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...

Sample policy

This is a basic GenerateAccessToken policy that is configured to accept the password grant type. For information on optional configuration elements that you can configure with this policy, see OAuthV2 policy.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
4

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns a JSON response. Note that with the password grant type, both an access token and refresh token are minted. For example:

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
5

If

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to false, the policy does not return a response. Instead, it populates the following set of flow variables with data pertaining to the access token grant.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
6

For example:

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
7

Use the implicit grant type

This section explains how to get an access token using the implicit grant type flow. See also What are OAuth 2.0 grant types.

Note: The OAuthV2 policy configuration in this section uses the
...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
5 operation. This operation generates an opaque string token format. You can also generate JWT-formatted tokens by substituting the
...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
6 operation. See also Using JWT OAuth token operations.

Sample request

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
8

Required parameters

By default, these parameters must be query parameters (as shown in the sample above); however, it is possible to change this default by configuring the

...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
7,
...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
8, and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
2 elements in the OAuthV2 policy that is attached to this
<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn> <!-- 30 minutes -->
    <SupportedGrantTypes>
      <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
0 endpoint. For details, see OAuthV2 policy.

User credentials are typically validated against a credential store using an LDAP service callout or JavaScript policy.

  • response_type - Must be set to the value
    <OAuthV2 name="GenerateAccessToken">
        <Operation>GenerateAccessToken</Operation>
        <ExpiresIn>1800000</ExpiresIn> <!-- 30 minutes -->
        <SupportedGrantTypes>
          <GrantType>client_credentials</GrantType>
        </SupportedGrantTypes>
        <GenerateResponse enabled="true"/>
    </OAuthV2>
    
    1.
  • client_id - The client ID of a registered developer app.
  • redirect_uri - This parameter is mandatory if a Callback URI was not provided when the client developer app was registered. If a Callback URL was provided at client registration, it will be compared to this value and must match exactly.

Optional parameters

  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

Does not require the Authorization header; however, you do need to pass a client ID as a request parameter.

Sample endpoint

Here's a sample endpoint configuration for generating an access token. It'll execute the GenerateAccessTokenImplicitGrant policy.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
9

Sample policy

This is a basic GenerateAccessTokenImplicitGrant policy that processes token requests for the implicit grant type flow. For information on optional configuration elements that you can configure with this policy, see OAuthV2 policy.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
0

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns a 302 Location redirect in the response header. The redirect points to the URL specified in the
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
4 parameter and is appended with the access token and token expiration time. Note that the implicit grant type does not support refresh tokens. For example:

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
1

If

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to false, the policy does not return a response. Instead, it populates the following set of flow variables with data pertaining to the access token grant.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
2

For example:

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
3

Get an authorization code

In the authorization code grant type flow, an authorization code is required to obtain an access token. See Use the authorization code grant type. See also What are OAuth 2.0 grant types.

Note: The authorization code flow takes place between a third-party user authentication service and Apigee. The intent of the authorization code grant type flow is that the client app never sees the user's credentials for the resource server. For a detailed look at this flow, see Implementing the authorization code grant type.

Sample request

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
4

Required parameters

By default, these parameters must be query parameters (as shown in the sample above); however, it is possible to change this default by configuring the

...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
7,
...   
       <Flow name="generate-access-token">
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
8, and
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
2 elements in the OAuthV2 policy. For details, see OAuthV2 policy.

  • redirect_uri - If a full (not partial) Callback URI is specified in the registered client app, this parameter is optional; otherwise, it is required. The callback is the URL where Apigee sends the newly minted auth code. See also Register apps and manage API keys.
  • response_type - Must be set to the value
    <OAuthV2 name="GenerateAccessToken">
        <Operation>GenerateAccessToken</Operation>
        <ExpiresIn>1800000</ExpiresIn> <!-- 30 minutes -->
        <SupportedGrantTypes>
          <GrantType>client_credentials</GrantType>
        </SupportedGrantTypes>
        <GenerateResponse enabled="true"/>
    </OAuthV2>
    
    8.
  • client_id - The client ID of a registered developer app.

Optional parameters

  • redirect_uri - If a full (not partial) Callback URI is specified in the registered client app, this parameter is optional; otherwise, it is required. The callback is the URL where Apigee sends the newly minted auth code. See also Register apps and manage API keys.
  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

Does not require the Authorization header, however the client ID of the registered client app must be supplied in the request.

Sample policy

This is a basic GenerateAuthorizationCode policy. For more configuration options, see OAuthV2 policy:

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
5

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
0 query parameter to the
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
4 (Callback URI) location with the authorization code attached. It is sent via a 302 browser redirect with the URL in the Location header of the response. For example:
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
2.

If

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
4, the policy does not return a response. Instead, it populates the following set of flow variables with data pertaining to the authorization code.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
6

For example:

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
7Note: You can also set custom attributes in the OAuthV2 policy. Custom attributes will be returned in the same format pattern as the other variables:
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
5. When you generate an access token from the auth code, the access token will inherit any custom variables set in the auth code. See also OAuthV2 policy.

Refreshing an access token

A refresh token is a credential you use to obtain an access token, typically after the access token has expired or becomes invalid. A refresh token is returned in the response when you receive an access token.

Note: The OAuthV2 policy configuration in this section uses the
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
6 operation. This operation refresjes an opaque string token format. You can also refresh JWT-formatted tokens by substituting the
{
    "issued_at": "1420260525643",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "scope": "READ",
    "status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "XkhU2DFnMGIVL2hvsRHLM00hRWav",
    "organization_name": "docs"
}
7 operation. See also Using JWT OAuth token operations.

Sample request

For information on encoding the basic authentication header in the following call, see Encoding basic authentication credentials.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
8

Required parameters

By default, the policy looks for these as

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
9 parameters specified in the request body, as shown in the example above. To configure an alternate location for these inputs, you can use the
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
0 and
...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
00 elements in the OAuthV2 policy. For details, see OAuthV2 policy.

  • grant_type - Must be set to the value
    ...   
           <Flow name="generate-access-token">
                <Description>Generate a token</Description>
                <Request>
                    <Step>
                        <Name>GenerateAccessToken</Name>
                    </Step>
                </Request>
                <Response/>
                <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
            </Flow>
    ...
    
    01.
  • refresh_token - The refresh token associated with the access token you wish to renew.

Optional parameters

  • state - A string that will be sent back with the response. Typically used to prevent cross-site request forgery attacks.
  • scope - Allows you to filter the list of API products with which the minted token can be used. For detailed information on scope, see Working with OAuth2 scopes.

Authorization

Does not require the Authorization header, however the client ID of the registered client app must be supplied in the request.

When refreshing an access token, there is no re-authentication of the user.

Here's a sample endpoint configuration for generating an access token using a refresh token. It'll execute the RefreshAccessToken policy.

<OAuthV2 name="GenerateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <SupportedGrantTypes>
      <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="true"/>
</OAuthV2>
9

Sample policy

This is a basic RefreshAccessToken policy that is configured to accept the

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
01 grant type. For information on optional configuration elements that you can configure with this policy, see OAuthV2 policy.

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
0

Returns

With

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 enabled, the policy returns a JSON response containing the new access token. The
...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
01 grant type supports minting both access and new refresh tokens. For example:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
1Note: The expiry of the access token and the refresh token noted in the response are 1 second less than specified in the policy configuration. This is due to transit time, and a margin of safety. And yes, it's kind of unusual to specify the expiry values in milliseconds in the policy, but receive them in seconds in the response payload. We are aware.

You should know that after a new refresh token is minted, the original is no longer valid.

The above response is what you get if

oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to true. If
oauthv2accesstoken.{policy-name}.access_token   
oauthv2accesstoken.{policy-name}.expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token
oauthv2accesstoken.{policy-name}.refresh_token_expires_in //--in seconds
oauthv2accesstoken.{policy-name}.refresh_token_issued_at
oauthv2accesstoken.{policy-name}.refresh_token_status
9 is set to false, the policy does not return a response. Instead, it populates the following set of context (flow) variables with data pertaining to the access token grant.

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
6

For example:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
3

Encoding basic authentication credentials

When you make an API call to request a token or auth code, it's a good practice, and is recommended by the OAuth 2.0 specification to pass the client_id and client_secret values as an HTTP-Basic Authorization header, as described in IETF RFC 2617. To do this, you must base64-encode the result of joining the two values together with a colon separating them.

In pseudo-code:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
4

Where:

...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
07 is the client_id and
...   
       <Flow name="generate-access-token">
            <Description>Generate a token</Description>
            <Request>
                <Step>
                    <Name>GenerateAccessToken</Name>
                </Step>
            </Request>
            <Response/>
            <Condition>(proxy.pathsuffix MatchesPath "/token") and (request.verb = "POST")</Condition>
        </Flow>
...
08 is the client secret.

Examples

This example command works on Linux and MacOS:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
5

Then, you can make the token request as follows:

{
    "issued_at": "1420262924658",
    "scope": "READ",
    "application_name": "ce1e94a2-9c3e-42fa-a2c6-1ee01815476b",
    "refresh_token_issued_at": "1420262924658",
    "status": "approved",
    "refresh_token_status": "approved",
    "api_product_list": "[PremiumWeatherAPI]",
    "expires_in": "1799", //--in seconds
    "developer.email": "[email protected]",
    "organization_id": "0",
    "token_type": "BearerToken",
    "refresh_token": "fYACGW7OCPtCNDEnRSnqFlEgogboFPMm",
    "client_id": "5jUAdGv9pBouF0wOH5keAVI35GBtx3dT",
    "access_token": "2l4IQtZXbn5WBJdL6EF7uenOWRsi",
    "organization_name": "docs",
    "refresh_token_expires_in": "86399", //--in seconds
    "refresh_count": "0"
}
6

Hashing tokens in the database

Apigee hashes all OAuth access and refresh tokens to protect them in the event of a database security breach. You use non-hashed tokens in API calls, and Apigee validates them against the hashed versions in the database.

How can I get token from authorization code?

The authorization code grant is used when an application exchanges an authorization code for an access token. After the user returns to the application via the redirect URL, the application will get the authorization code from the URL and use it to request an access token.

How do I generate access tokens?

In the upper-right corner of any page, click your profile photo, then click Settings. In the left sidebar, click Developer settings. In the left sidebar, under Personal access tokens, click Tokens (classic). Select Generate new token, then click Generate new token (classic).

How do I find my access token?

The high-level overview of validating an access token looks like this:.
Retrieve and parse your Okta JSON Web Keys (JWK), which should be checked periodically and cached by your application..
Decode the access token, which is in JSON Web Token format..
Verify the signature used to sign the access token..

How do I get my authorization bearer token?

How to get Bearer token.
After signing in into Platform of Trust Sandbox , open the developer tool in your browser..
Go to the Application tab. Refresh your browser tab once..
You will notice an Authorization cookie appearing. ... .
To use in the Insomnia workspace, exclude the "Bearer " part and copy the rest of the token..