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.
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
view_published_products and view_categories scopes enable the app to retrieve only published products and categories, but not to edit that data.manage_my_orders and manage_my_profile scopes, along with the Me endpoints.Create an OAuth client
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.
Copy or download the client credentials, they cannot be revealed after creation for security reasons.
Create a regular token with the 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} "
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
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
/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}"
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
/carts/), but the Me endpoints (such as /me/carts) instead.$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
POST /{projectKey}/me/carts with:{
"currency": "USD",
"country": "US"
}
customerId will be the ID of Alice.POST /{projectKey}/me/carts/<cart-id> with:{
"version": <cart-version>,
"actions": [{
"action": "addLineItem",
"productId": "<product-id>",
"variantId": 1,
"quantity": 1
}]
}
CORS and Browser Apps
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
/me endpoints. Now you can securely use the Composable Commerce APIs from a mobile app or a browser application!