OCAPI JWT 19.5

JSON Web Token (JWT) is an authentication mechanism required by several Shop API resources. You do not have to be completely familiar with JWT to use these resources; however, for more information about JWT, see the JSON Web Token (JWT) IETF specification.

Your client application is responsible for keeping customer credentials and authentication tokens (JWTs) secure. Your application must use these JWTs to interact with the Shop API on behalf of the purchasing customer (registered or guest).

Your client application can obtain a JWT for a customer by using the /customers/auth resource.

Preparation

Before you can use JWTs for authentication, you must register your client application using Account Manager. See Adding a client ID for the Open Commerce API.

Account Manager provides you with a client ID that is known to both Commerce Cloud Digital and your client application. The client ID is required when you request an authentication token. On sandboxes, for testing, you can use the demo client ID: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.

In addition to obtaining the authentication token, you must configure Open Commerce API Settings to grant your client application access to the Open Commerce APIs.

Authentication steps

To use JWTs for authentication, your client application must perform the following steps:

  1. Request a JWT using the /customers/auth resource.

  2. Include the JWT in subsequent Shop API requests.

  3. Refresh the JWT if needed.

When you request a JWT using the /customers/auth resource, you must specify your client ID as a URL or header parameter. You must also specify the type of customer:
  1. Specify "type":"guest" to request a JWT for a guest customer.
  2. Specify "type":"credentials" to request a JWT for a registered customer. (For a registered customer, you must also include the customer login and password in the HTTP Basic Authentication scheme.)
  3. Specify "type":"session" to request a JWT for a customer (guest or registered) associated with a session. (You have to provide valid dwsid and dwsecuretoken cookies.)
If the request succeeds, the response includes a JWT in the Authentication:Bearer response header. The response also includes a description of the customer in the response body. Your application must include the JWT in the Authentication:Bearer header of subsequent requests.

The JWT is signed. This means that the JWT's header and payload sections are JSON-formatted strings. Your client application can therefore easily read the various claims in the payload section, such as exp (the token expiration-time) and iat (the token issued-at-time).

A JWT has a lifetime of 30 minutes. Before the token expires, you must exchange it for a new token if you want to extend the total lifetime. You can use the /customers/auth resource to obtain a new token in exchange for an existing one. You must include the current token in the Authentication:Bearer request header, and you must specify the customer type as "type":"refresh".

The /customers/auth request is based on an HTTP POST operation, which uses transport layer security; the request body must be URL encoded. For registered customers, the client Id must be passed in the initial request to obtain the authentication token, but is not needed in subsequent requests.

JSON Web Token details

The JSON Web Token specification stipulates that a JWT contains three sections in the following order:

The system returns the JWT token as a Base64-encoded string. In this string, the header, payload, and signature sections are delimited by periods(.).

Digital uses a subset of the claims defined in the JSON Web Token specification. You can decode the payload section to access the values of the exp, iat, sub, and iss claims. For example:
{
      "exp": 1300819380,                      // token expiration-time as seconds from 1970-01-01T00:00:00Z
      "iat": 1300819000,                      // token issued-at-time as seconds from 1970-01-01T00:00:00Z
      "sub": ... ,                            // token subject (see below)
      "iss": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" // token issuer - the client ID
}
The value of the sub claim is a JSON string. For example:
{
      "customer_id":"12a4567f9123",           // customer id
      "guest":false                           // whether customer is guest (true) or registered (false)
}

Common JWT scenario: transferring a basket from a guest to a registered customer

A typical storefront enables a user to create and use a basket as a guest customer, and then continue to use the "same" basket after logging in as a registered customer. The Open Commerce API enables you to achieve this effect by copying the guest basket and using the new copy for the registered customer.

How you do this is described below:
  1. Request a JWT using the /shop/v19_5/customers/auth resource.

    In the body of the request, specify "guest" as the value of the "type" property: { "type" : "guest" }.

  2. Request a basket using the /shop/v19_5/baskets resource.

    In the request, include the JWT you obtained in the previous step.

  3. After performing additional OCAPI requests against the guest basket―for example, to create items, set a billing address, and so on―retain the last JSON response (a Basket document) in a variable.

  4. When the customer tries to log in as a registered customer, request a new JWT using the /shop/v19_5/customers/auth resource.

    In the request, specify "credentials" as the value of the "type" property: { "type" : "credentials" }.

    Also, in the request's Authorization header, specify the registered customer's login credentials.

  5. Request a new basket using the /shop/v19_5/baskets resource.

    In the request, include the basket document retained in step 3; also include the JWT obtained in the step 4.

    Note: The basket document must not be modified after it was last saved; it must be exactly the same as it was after the last request, with the same order of properties.

The new basket for the registered customer can now be modified and submitted as needed.

When creating baskets with a JWT, there is a limit of one open basket per registered customer. Exceeding this limit results in a CustomerBasketsQuotaExceededException fault response.

JWT examples

The following examples show sample requests and responses using JWTs for authentication (additional examples are provided within the resource documentation):

# Obtain a token for a registered customer.
# Credentials are username:password (Base64-encoded) passed via HTTP Basic Auth.

REQUEST:
POST /dw/shop/v19_5/customers/auth?client_id=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Host: example.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: application/json
{
  "type" : "credentials"
}


# If the server finds a customer with the given credentials, it returns a
# newly created token (a JWT) in the Authorization:Bearer response header.
# The value of the auth_type property is "registered" because the type
# property was set to "credentials" in the request.

RESPONSE:
HTTP/1.1 200 OK
Content-Length:124
Authorization:Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
Content-Type:application/json;charset=UTF-8
{
   "_v" : "19.5",
   "_type" : "customer",
   "auth_type" : "registered",
   "customer_id" : "abdtkZzH6sqInJGIHNR1yUw90A",
   "preferred_locale" : "default"
   ...
}


# All subsequent requests include the token in the Authorization:Bearer header.
# For example, the following request asks the server to create a new basket for
# the registered customer. The client ID is not required.

REQUEST:
POST /dw/shop/v19_5/baskets
Authorization:Bearer eyJfdiI6IjXXXXXX.eyJfdiI6IjEiLCJleHAXXXXXXX.-d5wQW4c4O4wt-Zkl7_fiEiALW1XXXX
Host: example.com
Content-Type: application/json


# The server returns information for the newly created basket.

RESPONSE:
HTTP/1.1 200 OK
Content-Length:124
Content-Type:application/json;charset=UTF-8
{
   "_v" : "19.5",
   "_resource_state" : "ba4e84383e1790597e49eeee34b201633d80ed3f499992f5af11d639dd903a36"
   "_type" : "basket",
   "basket_id" : "bczFTaOjgEqUkaaadkvHwbgrP5",
   "currency" : "USD",
   ....
}