Opcional. Um filtro de DNS, um bloqueador de anúncios ou uma rede que bloqueia o host da Korzen impede a tag, o beacon e a página de desafio. Esses visitantes continuam passando, julgados só pelo que o seu servidor envia, mas numa rota que exige o token da tag eles não conseguem passar. O modo first-party serve os três a partir de um caminho do seu próprio domínio, /kz se você não escolher outro, e os encaminha ao Bot Protection com o endereço do visitante. Nada bloqueia o caminho de um site sem bloquear o site.
Há duas formas de servir o caminho, e você pode usar as duas:
| A forma | O que você liga | Quem serve /kz |
|---|---|---|
| Só o SDK | firstParty: true no Node, FirstParty: true no Go | o seu servidor |
| Só o Worker | KORZEN_FIRST_PARTY = "1" e uma rota para /kz/* | o seu Cloudflare Worker |
| O Worker e o SDK | os dois, com o mesmo caminho | o Worker; o seu servidor manda para ele os visitantes desafiados |
Em qualquer forma, a página carrega a tag do seu caminho em vez do host da Korzen. A tag tira o seu endereço do próprio src, então toda requisição que ela faz também vai para /kz:
<script src="/kz/tag.js" data-site-key="YOUR_SITE_KEY" async></script>
O modo existe em todos os SDKs: Node (e o seu Worker), Go, Python, PHP, Java e .NET, cada um com a sua opção no README. Um cliente escrito a partir de um guia de framework não tem forwarder: nesse caso, use o SDK ou, atrás do Cloudflare, só o Worker, que dá o modo a uma origem em qualquer linguagem.
Só o SDK
O seu servidor serve o caminho. Passe a opção ao middleware que já consulta o Bot Protection e dê ao caminho um handler próprio com as mesmas opções. O client precisa ser criado por createClient, com a sua chave de API: o encaminhador a envia à Korzen em cada requisição.
// Express, with korzen.js as the Express guide sets it up const options = { client: korzen, ip: (_get, req) => req.ip, firstParty: true }; app.use("/kz", protect(options)); // before any body parser: it answers /kz/... itself app.use(express.urlencoded({ extended: false })); app.post("/signup", protect(options), signup); // Next.js: app/kz/[...path]/route.js serves the path const kz = withKorzen(() => new Response(null, { status: 404 }), { client, ip: ipFrom.vercel, firstParty: true }); export { kz as GET, kz as POST };
o := korzen.Options{IP: korzen.RemoteIP, FirstParty: true} mux.Handle("/kz/", bot.Protect(http.NotFoundHandler(), o)) // the path: Protect answers it itself mux.Handle("POST /signup", bot.Protect(http.HandlerFunc(signup), o))
- O que você liga.
firstParty: trueemprotectouwithKorzen(ligado só quando étrue); no Go,Options.FirstParty. Depois, osrcda tag nas suas páginas passa a ser/kz/tag.js. O endereço do visitante é lido como a decisão o lê: a opçãoip, no GoOptions.IP. - Um endereço que o visitante não pode escrever. O Korzen confia no endereço que o forwarder envia com a sua chave, então a opção
ipprecisa ler um que o visitante não pode definir:ipFrom.vercelsó na Vercel,ipFrom.cloudflare(Go:korzen.CloudflareIP) só se o seu servidor recebe tráfego apenas do Cloudflare,ipFrom.lastForwardedatrás do seu próprio load balancer ou nginx. Um cabeçalho que o visitante pode escrever deixa um script escolher o endereço que o Korzen julga. - O que muda para o visitante. Nada que ele veja. O navegador carrega a tag e envia o beacon ao seu domínio, então um visitante cuja rede bloqueia a Korzen é julgado com a evidência da tag e consegue fazer uma ação que exige o token dela. As requisições sob o caminho nunca são julgadas e nunca chegam aos seus handlers; todo outro caminho é julgado como antes.
- A página de desafio. Um carregamento de página desafiado vai para
/kz/challenge?c=…&r=…no seu domínio em vez do da Korzen, e o seu servidor encaminha a página, os arquivos dela e o envio. O mesmo desafio, e o visitante volta à página que pediu. - Fail open. Quando o Bot Protection está lento, fora do ar ou inalcançável pelo seu servidor, cada requisição sob o caminho responde
503com o corpo vazio, e a tag descarta esse sinal; a página e as suas outras rotas não esperam por nada. Fail open - Como saber se funciona.
curl -I https://shop.example/kz/tag.jsresponde200, e o painel de rede do navegador mostra as requisições da tag indo para o seu próprio domínio. Como saber se funciona
Só o Worker
O seu Cloudflare Worker serve o caminho, sem mudar nada no seu servidor, para uma origem em qualquer linguagem. Configure o Worker como mostra Cloudflare Workers, depois ligue o modo e adicione uma rota para o caminho:
# wrangler.toml
routes = [
{ pattern = "shop.example/kz/*", zone_name = "shop.example" },
{ pattern = "shop.example/signup*", zone_name = "shop.example" },
]
[vars]
KORZEN_URL = "https://korzen.dev"
KORZEN_FIRST_PARTY = "1"
# KORZEN_FIRST_PARTY_PATH = "/kz" # the path, /kz unless set
- O que você liga.
KORZEN_FIRST_PARTYcom1outrue(qualquer outro valor além de0oufalseo deixa desligado, com um aviso no log do Worker), uma rota parashop.example/kz/*e osrcda tag nas suas páginas como/kz/tag.js. O endereço do visitante é oCF-Connecting-IP, que o Cloudflare define. - O que muda para o visitante. Nada que ele veja. A tag e o beacon vão para o seu domínio, respondidos no edge do Cloudflare; a sua origem nunca vê essas requisições. As rotas do Worker são julgadas como antes.
- A página de desafio. Um carregamento de página que o Worker desafia vai para
/kz/challengeno seu domínio, que o Worker serve. - Fail open. O mesmo do SDK: um
503com o corpo vazio só para aquela requisição, e todas as outras seguem para a sua origem. Fail open - Como saber se funciona. Como abaixo; e
npx wrangler taillista as requisições sob/kz, enquanto o log de acesso da sua origem não mostra nenhuma. Como saber se funciona
O Worker e o SDK
Quando um Worker está na frente do seu site e o SDK roda na sua aplicação (para o context que só a sua aplicação conhece), ligue o modo nos dois, com o mesmo caminho.
- O que você liga. O Worker como acima, com a rota para
/kz/*, efirstParty: true(Go:FirstParty: true) no SDK atrás dele. O Worker responde/kz/*sozinho, então o SDK nunca vê essas requisições. - O que muda para o visitante. O mesmo que só com o Worker: a tag, o beacon e a página de desafio vêm do seu domínio, respondidos no edge.
- A página de desafio. O
firstPartydo SDK manda os visitantes que ele desafia para/kz/challengeem vez do host da Korzen, e o Worker serve essa página. Sem ele, um visitante que o SDK desafia vai para o host da Korzen, que a rede dele pode bloquear. - Fail open. Quem serve o caminho desiste por conta própria e responde
503; nenhum segura o outro. Se as rotas do Worker deixarem/kz/*de fora, ou o Worker for retirado, o SDK serve o caminho sozinho: atrás do Cloudflare, passe a eleip: ipFrom.cloudflare(Go:korzen.CloudflareIP). - Como saber se funciona. Como abaixo;
npx wrangler taillista as requisições sob/kz, e o log do seu servidor não mostra nenhuma.
O que o caminho serve
O encaminhador, o SDK ou o Worker, responde a estas e a nada mais:
| No seu domínio | O que é |
|---|---|
GET /kz/tag.js | a tag, com os headers de cache da Korzen |
GET /kz/n, POST /kz/s | o nonce da tag e o beacon (um corpo de no máximo 64 KiB) |
GET /kz/ping | respondido 204 pelo próprio encaminhador, nunca encaminhado |
GET e POST /kz/challenge, GET /kz/challenge/wait | a página de desafio e o envio dela (no máximo 16 KiB) |
GET /kz/static/… | o script, o estilo e as fontes da página de desafio |
Qualquer outro caminho sob /kz é um 404, e um conhecido com outro método um 405; nenhum dos dois chega ao Bot Protection, então o caminho nunca é um proxy aberto. À Korzen o encaminhador envia os headers do próprio navegador de uma lista curta (User-Agent, Accept, Accept-Language, Content-Type, Origin, Sec-Fetch-*, os client hints, If-None-Match), a sua chave de API como bearer e o endereço do visitante. Nunca um cookie, o Authorization do navegador ou um X-Forwarded-*. O que volta mantém os headers de cache e de segurança da Korzen, nunca um Set-Cookie.
A Korzen só aceita o endereço do visitante de uma requisição nessas rotas que traga a sua chave de API, e no beacon só para a sua própria site key; qualquer outra coisa é recusada com 403. A sua chave nunca chega ao navegador.
O cookie _kz da tag e o armazenamento dela continuam no seu domínio, como antes; os dados que a Korzen recebe são os mesmos. Algumas evidências que a Korzen só lê quando o navegador se conecta direto a ela não existem através de um encaminhador; o resto da evidência da tag chega, e nada do que falta conta contra um visitante.
Outro caminho
firstPartyPath (Go: Options.FirstPartyPath; o Worker: KORZEN_FIRST_PARTY_PATH) define outro caminho, por exemplo quando uma lista de bloqueio aprender /kz. Ele começa com /, termina sem uma, e tem no máximo 64 caracteres em segmentos de A-Z a-z 0-9 . _ ~ -. Um que não se lê é registrado no log uma vez, e o modo fica desligado. Use o mesmo caminho no src da tag, no SDK e no Worker.
Fail open
O caminho nunca segura a sua página nem as suas outras rotas:
- Cada requisição encaminhada desiste por conta própria: depois de 1 s num
GET, 2,5 s numPOST. Um timeout, um erro de rede, uma resposta acima de 4 MiB ou uma falha no encaminhador é um503com o corpo vazio eCache-Control: no-store; redirecionamentos não são seguidos. Os4xxe5xxdo próprio Bot Protection passam como vieram. - Sem o endereço do visitante (a opção
ipnão lê nenhum), o nonce, o beacon e o desafio respondem503; a tag e os arquivos da página de desafio continuam sendo servidos. - A tag então descarta esse sinal, como faz quando o host da Korzen está fora do ar. Uma tag que não reportou nunca é evidência de bot: o visitante é julgado pelo que o seu servidor envia.
Como saber se funciona
curl -I https://shop.example/kz/tag.jsresponde200, ecurl -I https://shop.example/kz/pingresponde204.- Nas ferramentas de desenvolvedor do navegador, numa página com a tag, o painel de rede mostra
/kz/tag.js,/kz/n,/kz/pinge/kz/sno seu próprio domínio, respondidos200ou204, e nenhuma requisição ao host da Korzen. - Faça uma ação protegida e depois clique em Verifique sua integração na página Configuração: O token da tag nessa chamada mostra Visto. As suas decisões aparecem como antes na página Decisões do painel.
- Com uma
Content-Security-Policy, o host da Korzen pode sair dela:script-src 'self'; connect-src 'self'; worker-src blob:basta para a tag. A tag
Erros comuns
- A tag ainda carregada do host da Korzen: o modo serve o caminho, mas só o
srcda tag leva o navegador até ele. - Um body parser antes do encaminhador no Express: o corpo do beacon é lido antes de o encaminhador recebê-lo. Monte-o antes de qualquer parser, ou só no caminho.
- O Worker com
KORZEN_FIRST_PARTYmas sem rota para/kz/*: as requisições chegam à sua origem, que responde404, a menos que o SDK sirva o caminho lá. - Dois caminhos: o Worker num e o SDK noutro. O SDK então manda os visitantes desafiados para um caminho que o Worker não serve.
- Chamar
/v1/decideà mão: ochallenge.urldele é sempre o host da Korzen. Só os SDKs e o Worker mandam o visitante para o seu caminho.