Skip to content

antoniodamous/fingerprint-tracking-worker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 

Repository files navigation

Desafio Técnico - Cloudflare Worker com D1

📌 Objetivo do Desafio

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.


🛠 Configuração do Ambiente

1️⃣ Criar uma Conta no Cloudflare (Gratuito)

Acesse https://dash.cloudflare.com/

2️⃣ Criando um Worker

  1. Vá até Compute (Workers)Workers & PagesCreateWorkersCreate Worker
  2. Insira o nome do Worker e substitua pelo código abaixo.
  3. Clique em "Save and Deploy".

2️⃣ Instalar Wrangler (CLI do Cloudflare Workers)

O Wrangler é uma ferramenta de linha de comando usada para desenvolver e gerenciar Cloudflare Workers.

  1. Instale o Wrangler globalmente:
    $ npm install -g wrangler
    
  2. Faça login no Cloudflare via Wrangler:
    $ wrangler login
    

3️⃣ Criar um Banco de Dados D1

  1. No painel do Cloudflare, vá até Workers & Pages > D1.
  2. Crie um novo banco de dados D1 e copie o nome para uso posterior.
  3. No terminal, execute:
    $ wrangler d1 create nome-do-seu-banco
    
  4. Para verificar a conexão:
    $ wrangler d1 list
    

📂 Estrutura do Projeto

/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

📝 Arquivos do Projeto

📄 wrangler.toml

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" }

📄 index.js

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 });
    }
};

📄 fingerprint.js

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': '*' }
    });
};

📄 db.js

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 });
};

📄 auth.js

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' }
    });
};

📄 package.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": {}
};

✅ Testes e Deploy

1️⃣ Rodar localmente

$ wrangler dev

2️⃣ Fazer deploy no Cloudflare

$ wrangler publish

3️⃣ Verificar logs

$ wrangler tail

🙇🏻‍♂️ Apredizado

🔗 Links

💻 Autor

Developed by Antônio Damous and Cloudflare 🥋


About

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.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors