Criar um Cloudflare Worker em JavaScript que capture fingerprints de sites e os armazene no Cloudflare D1. Além disso, deve fornecer uma rota autenticada para visualizar os acessos.
Acesse https://dash.cloudflare.com/
- Vá até Compute (Workers) → Workers & Pages → Create → Workers → Create Worker
- Insira o nome do Worker e substitua pelo código abaixo.
- Clique em "Save and Deploy".
O Wrangler é uma ferramenta de linha de comando usada para desenvolver e gerenciar Cloudflare Workers.
- Instale o Wrangler globalmente:
$ npm install -g wrangler - Faça login no Cloudflare via Wrangler:
$ wrangler login
- No painel do Cloudflare, vá até Workers & Pages > D1.
- Crie um novo banco de dados D1 e copie o nome para uso posterior.
- No terminal, execute:
$ wrangler d1 create nome-do-seu-banco - Para verificar a conexão:
$ wrangler d1 list
/desafio-fingerprint/
├── wrangler.toml
├── src/
│ ├── index.js # Código principal do Worker
│ ├── fingerprint.js # Script enviado ao navegador
│ ├── db.js # Funções de banco de dados D1
│ ├── auth.js # Lógica de autenticação
├── package.json
└── README.md
name = "desafio-fingerprint"
type = "javascript"
account_id = "SEU_ACCOUNT_ID"
workers_dev = true
compatibility_date = "2024-02-15"
[vars]
SECRET_KEY = "sua-chave-secreta"
[d1_databases]
DB = { binding = "DB", database_name = "nome-do-seu-banco", database_id = "SEU_DATABASE_ID" }import { handleFingerprintScript } from "./fingerprint";
import { handleCollect } from "./db";
import { handleView } from "./auth";
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (request.method === "OPTIONS") {
return handleOptions(request);
}
if (url.pathname === "/fingerprint.js") {
return handleFingerprintScript();
}
if (url.pathname === "/collect") {
return handleCollect(request, env);
}
if (url.pathname === "/view") {
return handleView(request, env);
}
return new Response("Rota não encontrada", { status: 404 });
}
};export async function handleFingerprintScript() {
const script = `
(async () => {
const fingerprintData = {
userAgent: navigator.userAgent,
platform: navigator.platform,
language: navigator.language,
screen: { width: screen.width, height: screen.height },
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
hardwareConcurrency: navigator.hardwareConcurrency,
deviceMemory: navigator.deviceMemory || 'unknown'
};
await fetch('/collect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fingerprintData)
});
})();
`;
return new Response(script, {
headers: { 'Content-Type': 'application/javascript', 'Access-Control-Allow-Origin': '*' }
});
};export async function handleCollect(request, env) {
if (request.method !== 'POST') {
return new Response('Método não permitido', { status: 405 });
}
const data = await request.json();
await env.DB.prepare('INSERT INTO fingerprints (data) VALUES (?)').bind(JSON.stringify(data)).run();
return new Response('Fingerprint salvo', { status: 200 });
};export async function handleView(request, env) {
const authHeader = request.headers.get('Authorization');
if (!authHeader || authHeader !== `Bearer ${env.SECRET_KEY}`) {
return new Response('Não autorizado', { status: 401 });
}
const { results } = await env.DB.prepare('SELECT * FROM fingerprints').all();
return new Response(JSON.stringify(results), {
headers: { 'Content-Type': 'application/json' }
});
};{
"name": "desafio-fingerprint",
"version": "1.0.0",
"description": "Cloudflare Worker para captura de fingerprints",
"main": "index.js",
"scripts": {
"start": "wrangler dev",
"deploy": "wrangler publish"
},
"dependencies": {},
"devDependencies": {}
};$ wrangler dev
$ wrangler publish
$ wrangler tail
- Documentação Cloudflare - https://developers.cloudflare.com/
- Documentação Javascript - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
- DOM - https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model
