# Implement mobile and browser apps commercetools provides OAuth scopes and endpoints designed to enable secure communication from a mobile or browser app with the commerce APIs. 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](/api/getting-started/initial-setup.md). ## 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](/api/scopes.md). 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](/api/authorization.md#password-flow) with the `manage_my_orders` and `manage_my_profile` scopes, along with the [Me endpoints](/api/me-endpoints-overview.md). ## 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](https://docs.commercetools.com/tutorials/images/create_new_mobile_api_client.png) 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](/api/authorization.md#client-credentials-flow). ```bash $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`: ```json { "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: ```bash $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](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/signup:POST). 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: ```json { "firstName": "Alice", "lastName": "Doe", "email": "alice@example.com", "password": "secret" } ``` The command could look like following: ```bash $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](/api/authorization.md#password-flow-for-global-customers). ```bash $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`: ```json { "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. ```bash $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](/api/me-endpoints-overview.md) (such as `/me/carts`) instead. For example, we can view their [account data](/search.md?urn=ctp:api:endpoint:/{projectKey}/me:GET): ```bash $curl -sH "Authorization: Bearer v-dZ10ZCpvbGfwcFniXqfkAj0vq1yZVI" https://api.{region}.commercetools.com/{projectKey}/me ``` or view their carts: ```bash $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](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/carts:POST): `POST /{projectKey}/me/carts` with: ```json { "currency": "USD", "country": "US" } ``` The My Carts create request looks similar to [Create Cart](/search.md?urn=ctp:api:endpoint:/{projectKey}/carts:POST), 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](/api/projects/me-carts.md#add-lineitem): `POST /{projectKey}/me/carts/` with: ```json { "version": , "actions": [{ "action": "addLineItem", "productId": "", "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 commercetools commerce APIs 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 commercetools commerce APIs from a mobile app or a browser application! ## Related pages - [Area overview page with navigation](/tutorials.md) - [Next page: Implement an API Extension](/tutorials/extensions.md) - [Search documentation and API specs](/search.md)