Skip to main content
Antes de começar
Language

Cloudflare Workers

Adicione cside Device Intelligence com um Cloudflare Worker gerenciado pelo cliente que injeta o script do navegador em respostas HTML.

Use este guia quando quiser implantar cside Device Intelligence no edge da Cloudflare. Esta é uma receita de Worker gerenciada pelo cliente. O cside não precisa gerenciar a sua conta Cloudflare para este setup.

Antes de começar

Você precisa de:

  • Uma zona Cloudflare que roteie tráfego para as páginas que você quer fingerprint
  • Permissão para criar ou editar Workers e rotas de Worker
  • A URL do script de cside Device Intelligence para o seu domínio, que pode encontrar no painel do cside
  • Uma chave de API de Device Intelligence apenas para backend gerada no dashboard do cside
  • Um endpoint backend que receba a string do token extraída da resposta JSON retornada por /client
Verifique rotas existentes

A Cloudflare permite apenas um Worker em uma rota correspondente. Se outro Worker já processa a mesma rota, combine a lógica ou escolha uma rota de teste mais estreita.

Rollout recomendado

Comece com uma rota limitada, como /login* ou /checkout*, antes de aplicar o Worker ao site inteiro. Mantenha o Worker fail-open para que um problema no cside ou no Worker não bloqueie a entrega da página.

Consulte o guia de Workers Routes da Cloudflare para saber como aplicar um Worker a uma rota.

Exemplo de Worker

Armazene a URL do script do cside como CSIDE_FINGERPRINT_SCRIPT_URL no ambiente do Worker.

function getFingerprintBootstrap(scriptURL) {
  return `<script>
(function () {
  const calls = [];
  let error;
  let timeoutID;

  function fallback(externalIds) {
    return error
      ? Promise.reject(error)
      : new Promise((resolve, reject) => {
          calls.push({ externalIds, resolve, reject });
        });
  }

  function rejectAll(nextError) {
    if (error) {
      return;
    }

    error = nextError;
    while (calls.length > 0) {
      calls.shift().reject(nextError);
    }
  }

  function flush(sendClientTelemetry) {
    while (calls.length > 0) {
      const call = calls.shift();
      Promise.resolve()
        .then(() => sendClientTelemetry(call.externalIds))
        .then(call.resolve, call.reject);
    }
  }

  window.sendClientTelemetry = window.sendClientTelemetry || fallback;

  const script = document.createElement("script");
  script.async = true;
  script.src = ${JSON.stringify(scriptURL)};
  script.referrerPolicy = "origin";
  script.setAttribute("data-src", "6");

  const fail = (nextError) => {
    clearTimeout(timeoutID);
    rejectAll(nextError);
  };

  script.onerror = () =>
    fail(new Error("cside client.js failed to load"));
  script.onload = () => {
    clearTimeout(timeoutID);
    const sendClientTelemetry = window.sendClientTelemetry;
    if (
      typeof sendClientTelemetry !== "function" ||
      sendClientTelemetry === fallback
    ) {
      rejectAll(new Error("cside telemetry unavailable"));
      return;
    }
    flush(sendClientTelemetry);
  };

  timeoutID = setTimeout(
    () => fail(new Error("cside client.js timed out while loading")),
    10000,
  );
  (document.head || document.documentElement).appendChild(script);
})();
</script>`;
}

export default {
  async fetch(request, env) {
    const response = await fetch(request);
    const contentType = response.headers.get("content-type") || "";

    if (!contentType.includes("text/html")) {
      return response;
    }

    try {
      return new HTMLRewriter()
        .on("head", {
          element(element) {
            element.append(
              getFingerprintBootstrap(env.CSIDE_FINGERPRINT_SCRIPT_URL),
              { html: true },
            );
          },
        })
        .transform(response);
    } catch {
      return response;
    }
  },
};

Troca do token

O Worker injeta apenas o script do navegador. Ele não cria um fingerprint de sessão sozinho. A sua aplicação ainda chama sendClientTelemetry(externalIds?), recebe { token } de /client e envia esse token de sessão ao seu backend.

Gere uma chave de API de Device Intelligence no dashboard do cside antes de conectar a troca no backend. A chave começa com cside_tgatv1_, é exibida apenas uma vez e deve ser armazenada como segredo do servidor. Não a inclua em código de navegador.

Chame sendClientTelemetry no código da sua página ou aplicação depois que o script carregar e, em seguida, leia a resposta JSON retornada por /client:

const result = await sendClientTelemetry({
  email: "user@example.com",
  accountId: "1234567890",
});

if (result.errors) {
  console.error(result.errors);
  throw new Error("A solicitação de telemetria falhou.");
}

const { token: sessionToken } = result;

if (!sessionToken) {
  throw new Error("Nenhum token de sessão de fingerprint foi retornado.");
}

await fetch("/api/fingerprinting", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ sessionToken }),
});

/client retorna JSON no formato { "token": "..." }. Você também pode chamar sendClientTelemetry() sem argumentos quando não precisar anexar externalIds.

O seu backend troca o token de sessão com o cside chamando o endpoint de verificação autenticado:

curl https://api.cside.com/token/v2/verify \
  --request POST \
  --header "Authorization: Bearer $CSIDE_FINGERPRINT_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"token":"'"$CSIDE_FINGERPRINT_SESSION_TOKEN"'"}'

Exemplo de handler backend:

app.post("/api/fingerprinting", async (request, reply) => {
  const { sessionToken } = request.body;

  const csideResponse = await fetch("https://api.cside.com/token/v2/verify", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.CSIDE_FINGERPRINT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ token: sessionToken }),
  });

  const payload = await csideResponse.json();

  if (!csideResponse.ok) {
    throw new Error(payload.error_message || "A troca de fingerprint falhou.");
  }

  reply.code(csideResponse.status).send(payload);
});

Consulte Recuperar datapoints para ver as opções de recuperação.

Notas operacionais

  • Use rotas estreitas para o primeiro rollout
  • Mantenha o Worker fail-open
  • Não injete o script em respostas que não sejam HTML
  • Confirme que a sua CSP permite a URL do script do cside e o endpoint de troca do token
  • Mantenha a chave de API de Device Intelligence apenas em segredos do backend
  • Passe de caminhos de teste para cobertura completa depois de ver datapoints no cside
Was this page helpful?