Tutorial Tutorial Application Services Application Services ~40 phút ~40 min Đồng bộ 2026-06-10 Synced 2026-06-10

Cấu hình your mobile app or IoT device Configure your mobile app or IoT device

Hướng dẫn chi tiết đồng bộ từ docs Cloudflare — mỗi section có backlink tới đúng vị trí trên trang gốc. Detailed guide synced from Cloudflare docs — each section links to the matching anchor on the official page.

← Danh mục ← Catalog

Giải thích nhanh Quick context

Thuộc nhóm Application Services — tập trung bảo vệ, tăng tốc và vận hành ứng dụng/web phía trước origin. Tutorial «Cấu hình your mobile app or IoT device» giúp bạn làm quen luồng triển khai thật — phù hợp đọc trước khi mở tài liệu gốc tiếng Anh. Docs gốc chia khoảng 5 bước chính; bản tóm tắt dưới đây giúp bạn nắm khung trước khi làm theo từng lệnh.

This tutorial demonstrates how to configure your Internet-of-things (IoT) device and mobile application to use client certificates with API Shield.

Lưu ý trước khi làm Notes before you start

  • Đây là bản tóm tắt trên Orange Cloud Learning Hub — không thay thế tài liệu chính thức. This is a summary on Orange Cloud Learning Hub — it does not replace the official documentation.
  • Luôn mở liên kết «Tài liệu gốc» bên dưới khi cần lệnh CLI, snippet code và ảnh minh họa đầy đủ. Open the Official docs link below for CLI commands, code snippets, and full screenshots.
  • Docs Cloudflare cập nhật thường xuyên — đối chiếu ngày «Rà soát lần cuối» trên trang gốc khi triển khai production. Cloudflare docs change frequently — verify the Last reviewed date on the official page before production use.

Tổng quan Overview

Phần «Tổng quan» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "Overview" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

This tutorial demonstrates how to configure your Internet-of-things (IoT) device and mobile application to use client certificates with API Shield.

Liên kết liên quan (docs Cloudflare) Related links (Cloudflare docs)

Scenario details Scenario details

Phần «Scenario details» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "Scenario details" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

This walkthrough uses the example of a device that captures temperature readings and transmits them by sending a POST request to a Cloudflare-protected API. A mobile application built in Swift for iOS retrieves those readings and displays them.

To keep this example simple, the API is implemented as a Cloudflare Worker (borrowing code from the To-Do List tutorial on building a jamstack app).

Temperatures are stored in Workers KV using the source IP address as a key, but you can easily use a value from the client certificate, such as the fingerprint.

The example API code below saves a temperature and timestamp into KV when a POST is made and returns the most recent five temperatures when a GET request is made.

JavaScript

text
const defaultData = { temperatures: [] };


const getCache = (key) => TEMPERATURES.get(key);

const setCache = (key, data) => TEMPERATURES.put(key, data);


async function addTemperature(request) {

  // Pull previously recorded temperatures for this client.

  const ip = request.headers.get("CF-Connecting-IP");

  const cacheKey = `data-${ip}`;

  let data;

  const cache = await getCache(cacheKey);

  if (!cache) {

    await setCache(cacheKey, JSON.stringify(defaultData));

    data = defaultData;

  } else {

    data = JSON.parse(cache);

  }


  // Append the recorded temperatures with the submitted reading (assuming it has both temperature and a timestamp).

  try {

    const body = await request.text();

    const val = JSON.parse(body);


    if (val.temperature && val.time) {

      data.temperatures.push(val);

      await setCache(cacheKey, JSON.stringify(data));

      return new Response("", { status: 201 });

    } else {

      return new Response(

        "Unable to parse temperature and/or timestamp from JSON POST body",

        { status: 400 },

      );

    }

  } catch (err) {

    return new Response(err, { status: 500 });

  }

}


function compareTimestamps(a, b) {

  return -1 * (Date.parse(a.time) - Date.parse(b.time));

}


// Return the 5 most recent temperature measurements.

async function getTemperatures(request) {

  const ip = request.headers.get("CF-Connecting-IP");

  const cacheKey = `data-${ip}`;


  const cache = await getCache(cacheKey);

  if (!cache) {

    return new Response(JSON.stringify(defaultData), {

      status: 200,

      headers: { "content-type": "application/json" },

    });

  } else {

    data = JSON.parse(cache);

    const retval = JSON.stringify(

      data.temperatures.sort(compareTimestamps).splice(0, 5),

    );

    return new Response(retval, {

      status: 200,

      headers: { "content-type": "application/json" },

    });

  }

}


export default {

  async fetch(request, env, ctx) {

    return request.method === "POST"

      ? addTemperature(request)

      : getTemperatures(request);

  },

};

---

POST sample data to API POST sample data to API

Phần «POST sample data to API» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "POST sample data to API" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

To validate the API before adding mTLS authentication, POST a random temperature reading:

Terminal window

text
$ TEMPERATURE=$(echo $((361 + RANDOM %11)) | awk '{printf("%.2f",$1/10.0)}')

$ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")


$ echo -e "$TEMPERATURE\n$TIMESTAMP"

36.70

2020-09-28T02:54:56Z


$ curl --verbose --header "Content-Type: application/json" --data '{"temperature":'''$TEMPERATURE''', "time": "'''$TIMESTAMP'''"}' https://shield.upinatoms.com/temps 2>&1 | grep "< HTTP/2"

< HTTP/2 201

GET sample data từ API GET sample data from API

Phần «GET sample data từ API» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "GET sample data from API" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

A GET request to the temps endpoint returns the most recent readings, including the one submitted in the example above:

Terminal window

text
$ curl --silent https://shield.upinatoms.com/temps | jq .

[

  {

    "temperature": 36.3,

    "time": "2020-09-28T02:57:49Z"

  },

  {

    "temperature": 36.7,

    "time": "2020-09-28T02:54:56Z"

  },

  {

    "temperature": 36.2,

    "time": "2020-09-28T02:33:08Z"

  }

]

---

2. Tạo Cloudflare-issued certificates 2. Create Cloudflare-issued certificates

Phần «Tạo Cloudflare-issued certificates» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "2. Create Cloudflare-issued certificates" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

Before you can use API Shield to protect your API or web application, create Cloudflare-issued client certificates.

You can create a client certificate in the Cloudflare dashboard.

However, since most developers working at scale generate their own private keys and certificate signing requests via API, this example uses the Cloudflare API to create client certificates.

To create a bootstrap certificate for the iOS application and the IoT device, this example uses Cloudflare’s public key infrastructure toolkit, CFSSL ↗:

Terminal window

text
# Generate a private key and CSR for the iOS device.


$ cat <<'EOF' | tee -a csr.json

{

    "hosts": [

        "ios-bootstrap.devices.upinatoms.com"

    ],

    "CN": "ios-bootstrap.devices.upinatoms.com",

    "key": {

        "algo": "rsa",

        "size": 2048

    },

    "names": [{

        "C": "US",

        "L": "Austin",

        "O": "Temperature Testers, Inc.",

        "OU": "Tech Operations",

        "ST": "Texas"

    }]

}

EOF


$ cfssl genkey csr.json | cfssljson -bare certificate


2020/09/27 21:28:46 [INFO] generate received request

2020/09/27 21:28:46 [INFO] received CSR

2020/09/27 21:28:46 [INFO] generating key: rsa-2048

2020/09/27 21:28:47 [INFO] encoded CSR


$ mv certificate-key.pem ios-key.pem

$ mv certificate.csr ios.csr


# Do the same for the IoT sensor.


$ sed -i.bak 's/ios-bootstrap/sensor-001/g' csr.json

$ cfssl genkey csr.json | cfssljson -bare certificate

...

$ mv certificate-key.pem sensor-key.pem

$ mv certificate.csr sensor.csr


# now ask that these CSRs be signed by the private CA issued for your zone

# we need to replace actual newlines in the CSR with ‘\n’ before POST’ing

$ CSR=$(cat ios.csr | perl -pe 's/\n/\\n/g')

$ request_body=$(< <(cat <<EOF

{

  "validity_days": 3650,

  "csr":"$CSR"

}

EOF

))


# save the response so we can view it and then extra the certificate

$ curl https://api.cloudflare.com/client/v4/zones/{zone_id}/client_certificates \

--header "X-Auth-Email: <EMAIL>" \

--header "X-Auth-Key: <API_KEY>" \

--header "Content-Type: application/json" \

--data "$request_body" > response.json


$ cat response.json | jq .


{

  "success": true,

  "errors": [],

  "messages": [],

  "result": {

    "id": "7bf7f70c-7600-42e1-81c4-e4c0da9aa515",

    "certificate_authority": {

      "id": "8f5606d9-5133-4e53-b062-a2e5da51be5e",

      "name": "Cloudflare Managed CA for account 11cbe197c050c9e422aaa103cfe30ed8"

    },

    "certificate": "-----BEGIN CERTIFICATE-----\nMIIEkzCCA...\n-----END CERTIFICATE-----\n",

    "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIDITCCA...\n-----END CERTIFICATE REQUEST-----\n",

    "ski": "eb2a48a19802a705c0e8a39489a71bd586638fdf",

    "serial_number": "133270673305904147240315902291726509220894288063",

    "signature": "SHA256WithRSA",

    "common_name": "ios-bootstrap.devices.upinatoms.com",

    "organization": "Temperature Testers, Inc.",

    "organizational_unit": "Tech Operations",

    "country": "US",

    "state": "Texas",

    "location": "Austin",

    "expires_on": "2030-09-26T02:41:00Z",

    "issued_on": "2020-09-28T02:41:00Z",

    "fingerprint_sha256": "84b045d498f53a59bef53358441a3957de81261211fc9b6d46b0bf5880bdaf25",

    "validity_days": 3650

  }

}


$ cat response.json | jq .result.certificate | perl -npe 's/\\n/\n/g; s/"//g' > ios.pem


# Now ask that the second client certificate signing request be signed.


$ CSR=$(cat sensor.csr | perl -pe 's/\n/\\n/g')

$ request_body=$(< <(cat <<EOF

{

  "validity_days": 3650,

  "csr":"$CSR"

}

EOF

))


$ curl https://api.cloudflare.com/client/v4/zones/{zone_id}/client_certificates \

--header "X-Auth-Email: <EMAIL>" \

--header "X-Auth-Key: <API_KEY>" \

--header "Content-Type: application/json" \

--data "$request_body" | perl -npe 's/\\n/\n/g; s/"//g' > sensor.pem

---

Liên kết liên quan (docs Cloudflare) Related links (Cloudflare docs)

3. Embed client certificate in your mobile app 3. Embed the client certificate in your mobile app

Phần «Embed client certificate in your mobile app» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "3. Embed the client certificate in your mobile app" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

To configure the mobile app to securely request temperature data submitted by the IoT device, embed the client certificate in the mobile app.

For simplicity, this example embeds a “bootstrap” certificate and key in the application bundle as a PKCS#12-formatted file:

Terminal window

text
$ openssl pkcs12 -export -out bootstrap-cert.pfx -inkey ios-key.pem -in ios.pem

Enter Export Password:

Verifying - Enter Export Password:

In a real-world deployment, a bootstrap certificate should only be used in conjunction with users' credentials to authenticate with an API endpoint that can return a unique user certificate. Corporate users will want to use mobile device management (MDM) to distribute certificates.

Embed client certificate in Android app Embed the client certificate in an Android app

Phần «Embed client certificate in Android app» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "Embed the client certificate in an Android app" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

The following is an example of how you may use a client certificate in an Android app to make HTTP calls. You need to add the following permission in AndroidManifest.xml to allow an Internet connection.

text
<uses-permission android:name="android.permission.INTERNET" />

For demonstration purposes, the certificate in this example is stored in app/src/main/res/raw/cert.pem and the private key is stored in app/src/main/res/raw/key.pem. You may also store these files in other secure manners.

The following example uses an OkHttpClient, but you may also use other clients such as HttpURLConnection in similar ways. The key is to use the SSLSocketFactory.

text
private OkHttpClient setUpClient() {

    try {

        final String SECRET = "secret"; // You may also store this String somewhere more secure.

        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");


        // Get private key

        InputStream privateKeyInputStream = getResources().openRawResource(R.raw.key);

        byte[] privateKeyByteArray = new byte[privateKeyInputStream.available()];

        privateKeyInputStream.read(privateKeyByteArray);


        String privateKeyContent = new String(privateKeyByteArray, Charset.defaultCharset())

                .replace("-----BEGIN PRIVATE KEY-----", "")

                .replaceAll(System.lineSeparator(), "")

                .replace("-----END PRIVATE KEY-----", "");


        byte[] rawPrivateKeyByteArray = Base64.getDecoder().decode(privateKeyContent);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivateKeyByteArray);


        // Get certificate

        InputStream certificateInputStream = getResources().openRawResource(R.raw.cert);

        Certificate certificate = certificateFactory.generateCertificate(certificateInputStream);


        // Set up KeyStore

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

        keyStore.load(null, SECRET.toCharArray());

        keyStore.setKeyEntry("client", keyFactory.generatePrivate(keySpec), SECRET.toCharArray(), new Certificate[]{certificate});

        certificateInputStream.close();


        // Set up Trust Managers

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

        trustManagerFactory.init((KeyStore) null);

        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();


        // Set up Key Managers

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

        keyManagerFactory.init(keyStore, SECRET.toCharArray());

        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();


        // Obtain SSL Socket Factory

        SSLContext sslContext = SSLContext.getInstance("TLS");

        sslContext.init(keyManagers, trustManagers, new SecureRandom());

        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();


        // Finally, return the client, which will then be used to make HTTP calls.

        OkHttpClient client = new OkHttpClient.Builder()

                .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0])

                .build();


        return client;


    } catch (CertificateException | IOException | NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException | KeyManagementException | InvalidKeySpecException e) {

        e.printStackTrace();

        return null;

    }

}

The above function returns an OkHttpClient embedded with the client certificate. You can now use this client to make HTTP requests to your API endpoint protected with mTLS.

---

4. Embed client certificate on your IoT device 4. Embed the client certificate on your IoT device

Phần «Embed client certificate on your IoT device» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "4. Embed the client certificate on your IoT device" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

To prepare the IoT device for secure communication with the API endpoint, embed the certificate on the device and configure the device to use the certificate when making POST requests.

This example assumes the certificate and the private key are securely copied to /etc/ssl/private/sensor-key.pem and /etc/ssl/certs/sensor.pem.

The sample script is modified to point to these files:

Python

text
import requests

import json

from datetime import datetime


def readSensor():


    # Takes a reading from a temperature sensor and store it to temp_measurement


    dateTimeObj = datetime.now()

    timestampStr = dateTimeObj.strftime('%Y-%m-%dT%H:%M:%SZ')


    measurement = {'temperature':str(temp_measurement),'time':timestampStr}

    return measurement


def main():


    print("Cloudflare API Shield [IoT device demonstration]")


    temperature = readSensor()

    payload = json.dumps(temperature)


    url = 'https://shield.upinatoms.com/temps'

    json_headers = {'Content-Type': 'application/json'}

    cert_file = ('/etc/ssl/certs/sensor.pem', '/etc/ssl/private/sensor-key.pem')


    r = requests.post(url, headers = json_headers, data = payload, cert = cert_file)


    print("Request body: ", r.request.body)

    print("Response status code: %d" % r.status_code)

When the script attempts to connect to https://shield.upinatoms.com/temps, Cloudflare requests that a client certificate is sent and the script sends the contents of /etc/ssl/certs/sensor.pem. Then, as required to complete the SSL/TLS handshake, the script demonstrates it has possession of /etc/ssl/private/sensor-key.pem.

Without the client certificate, the Cloudflare rejects the request:

text
Cloudflare API Shield [IoT device demonstration]

Request body:  {"temperature": "36.5", "time": "2020-09-28T15:52:19Z"}

Response status code: 403

When the IoT device presents a valid client certificate, the POST request succeeds and the temperature reading is recorded:

text
Cloudflare API Shield [IoT device demonstration]

Request body:  {"temperature": "36.5", "time": "2020-09-28T15:56:45Z"}

Response status code: 201

---

5. Enable mTLS 5. Enable mTLS

Phần «Enable mTLS» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "5. Enable mTLS" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

After creating Cloudflare-issued certificates, the next step is to enable mTLS for the hosts you want to protect with API Shield.

---

Liên kết liên quan (docs Cloudflare) Related links (Cloudflare docs)

6. Cấu hình API Shield to require client certificates 6. Configure API Shield to require client certificates

Phần «Cấu hình API Shield to require client certificates» — đọc hướng dẫn bên dưới, dùng liên kết docs gốc để xem ảnh minh họa và tab cấu hình đầy đủ.

Read the "6. Configure API Shield to require client certificates" section below — open the official docs link for full screenshots and configuration tabs.

Mở section docs gốc ↗ Open source section ↗

To configure API Shield to require client certificates, create a mTLS rule.

json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ssl/","name":"SSL/TLS"}},{"@type":"ListItem","position":3,"item":{"@id":"/ssl/client-certificates/","name":"Client certificates (mTLS)"}},{"@type":"ListItem","position":4,"item":{"@id":"/ssl/client-certificates/configure-your-mobile-app-or-iot-device/","name":"Configure your mobile app or IoT device"}}]}

Liên kết liên quan (docs Cloudflare) Related links (Cloudflare docs)

Xem bản đầy đủ trên developers.cloudflare.com (ảnh, tab cấu hình). View the full guide on developers.cloudflare.com (images, config tabs).

Tài liệu gốc ↗ Official docs ↗