Implement mobile and browser apps

Ask about this Page
Copy for LLM
View as Markdown

commercetools Composable Commerce offers OAuth scopes and endpoints designed to enable secure communication with the API from a mobile or browser app. This tutorial shows you how to use them. It walks you through how to display Products, create a Customer account, and add a Product to a Cart.

To follow this tutorial, you should have a Project set up, as described in Getting Started.

Why we can't trust a mobile or browser app like a server

When we write a frontend that renders webpages on a server, you can trust that server-rendered code is secured from inspection. No man-in-the-middle attack can be performed because we control which certificates are trusted. However, when code runs on a mobile device or inside a browser, inspecting client-side code is straightforward. A malicious actor could extract secrets such as the OAuth client or perform a man-in-the-middle attack to steal an OAuth token.

The frontend server has far-reaching access to the data, such as the orders of all customers. You can trust the server to use the API appropriately, rendering only order data of the customer logged into the session. If we gave the same access to an app, a hacker could steal an OAuth token. The stolen token could be used to access the order data of all customers.

Limit access with OAuth scopes

To limit the access of an app to the data it can view or edit via the API, we can use OAuth scopes. The app should not be able to edit products, but the app should display them. The view_published_products and view_categories scopes enable the app to retrieve only published products and categories, but not to edit that data.
We want to give the app access to some data only when it acts on behalf of a customer. The app should not access orders of all customers, but if a customer has logged in, the app should access that customer's order data. To achieve this, use the OAuth password flow with the manage_my_orders and manage_my_profile scopes, along with the Me endpoints.

Create an OAuth client

First, we need to create an OAuth client with the permissions view_published_products, manage_my_orders and manage_my_profile and view_categories. In the Merchant Center, go to the "Developer Settings" section and create a new API Client with the template "Mobile client & single-page application client" that contains the required permissions.
Screenshot Create New Mobile API Client

Copy or download the client credentials, they cannot be revealed after creation for security reasons.

Create a regular token with the Client Credentials Flow

If we don't want to force the customer to log in when opening the app, we must use the API without the OAuth password flow. We use the OAuth client we just created to get a regular token with the three scopes we need. For the full token request format and parameters, see Client credentials flow.
$curl https://auth.{region}.commercetools.com/oauth/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=client_credentials&scope=view_published_products:{projectKey} manage_my_profile:{projectKey} view_categories:{projectKey} "
The response contains the token in the field access_token:
{
  "access_token": "vkFuQ6oTwj8_Ye4eiRSsqMeqLYNeQRJi",
  "token_type": "Bearer",
  "expires_in": 172800,
  "refresh_token": "{projectKey}:OWStLG0eaeVs7Yx3-mHcn8iAZohBohCiJSDdK1UCJ9U",
  "scope": "view_published_products:{projectKey} manage_my_profile:{projectKey} view_categories:{projectKey}"
}

The client credentials token can now be used to access products, for example:

$curl -sH "Authorization: Bearer vkFuQ6oTwj8_Ye4eiRSsqMeqLYNeQRJi" https://api.{region}.commercetools.com/{projectKey}/product-projections?staged=true&limit=10

Create a new Customer

Eventually, the customer will either need to log in or create a new account. The manage_my_profile scope authorizes the token to sign up a customer.

After we have collected important information like name, email, and password from the customer, we can send their data to the API:

POST /{projectKey}/me/signup with:
{
  "firstName": "Alice",
  "lastName": "Doe",
  "email": "alice@example.com",
  "password": "secret"
}

The command could look like following:

$curl -sH "Authorization: Bearer {access_token}" -X POST -d '{"firstName": "Alice","lastName": "Doe","email": "alice1@example.com","password": "secret"}' https://api.{region}.commercetools.com/{projectKey}/me/signup

Create a token bound to a Customer with the Password Flow

Let's create a Password Flow token for this customer (note that we use /oauth/{projectKey}/customers/token now). For the full token request format, see Password flow for global Customers.
$curl https://auth.{region}.commercetools.com/oauth/{projectKey}/customers/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=password&username=alice@example.com&password=secret&scope=view_published_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey} view_categories:{projectKey}"
In addition to the regular access_token, this response also contains the refresh_token:
{
  "access_token": "v-dZ10ZCpvbGfwcFniXqfkAj0vq1yZVI",
  "expires_in": 172800,
  "scope": "view_published_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey}",
  "refresh_token": "{projectKey}:OWStLG0eaeVs7Yx3-mHcn8iAZohBohCiJSDdK1UCJ9U",
  "token_type": "Bearer"
}

We can save the refresh token securely (for example on the mobile device) to get a new access token, without saving the email or password of the user.

$curl https://auth.{region}.commercetools.com/oauth/{projectKey}/customers/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=refresh_token&refresh_token={projectKey}:OWStLG0eaeVs7Yx3-mHcn8iAZohBohCiJSDdK1UCJ9U"

Note that if the customer changes their password, access tokens and refresh tokens become invalid and your app has to ask the user for the new password to get new tokens.

Use a Password Flow token

Our password flow token can be used for the same requests as before, for example we can retrieve a list of products. But we can also access data specific to the customer we've logged in with. We don't use the regular endpoints (such as /carts/), but the Me endpoints (such as /me/carts) instead.
For example, we can view their account data:
$curl -sH "Authorization: Bearer v-dZ10ZCpvbGfwcFniXqfkAj0vq1yZVI" https://api.{region}.commercetools.com/{projectKey}/me

or view their carts:

$curl -sH "Authorization: Bearer v-dZ10ZCpvbGfwcFniXqfkAj0vq1yZVI" https://api.{region}.commercetools.com/{projectKey}/me/carts

Write with a Password Flow token

We also have write access to the data of the customer. For example, we can create a new cart:
POST /{projectKey}/me/carts with:
{
  "currency": "USD",
  "country": "US"
}
The My Carts create request looks similar to Create Cart, but has a key difference: the cart automatically belongs to the logged-in customer. For example, the customerId will be the ID of Alice.
We can now use this cart much like we're using any other cart, for example we can add a line item:
POST /{projectKey}/me/carts/<cart-id> with:
{
  "version": <cart-version>,
  "actions": [{
    "action": "addLineItem",
    "productId": "<product-id>",
    "variantId": 1,
    "quantity": 1
  }]
}

CORS and Browser Apps

Cross-origin resource sharing (CORS) is a mechanism implemented in web browsers, which will either allow or deny requests coming from your web app to the commercetools servers. When your app sends an HTTP request to our domain, the browser will send an additional preflight request, to see which headers are accepted by our servers. Currently, the Composable Commerce API will respond with the following Access-Control-Allow-Headers value: Accept, Authorization, Content-Type, Origin, User-Agent, X-Correlation-ID. The Access-Control-Allow-Headers value means you can use these 6 headers when sending requests from your browser apps directly to our servers.

Conclusion

You've seen how to get a regular token to view products without having to log in a customer, how to get a token with the password flow and how to use it with the /me endpoints. Now you can securely use the Composable Commerce APIs from a mobile app or a browser application!