SDK de servidor para Node.js
@fingertrackid/server é o cliente do FingerTrackID para um backend Node.js. Ele monta cada
requisição com as mesmas regras que a API aplica, assina-a com o
assinador de referência, faz
nova tentativa apenas do que o catálogo publicado de Problems marca como passível de nova tentativa
e devolve cada caso como um resultado. Ele nunca lança exceção depois da inicialização, então o seu
produto mantém a própria decisão quando o FingerTrackID está lento ou indisponível.
O SDK é opcional. Qualquer backend que siga as regras de autenticação e reproduza o vetor de teste público se integra da mesma forma; os contratos publicados prevalecem sobre o SDK, como sobre qualquer exemplo.
Instale
Seção intitulada “Instale”Node.js 24.16 ou mais recente na série 24, ou 26.1 ou mais recente. Fixe a versão exata.
self-check reproduz o vetor público de assinatura no Node.js que o executa e não precisa de
credencial.
O pacote não tem dependência em tempo de instalação nem script de instalação: é um único bundle não
minificado que você pode ler, com as licenças de código aberto que ele carrega em
THIRD-PARTY-NOTICES.txt. Compare o integrity do seu lockfile com
npm view @fingertrackid/server@0.1.2 dist.integrity.
npm install --save-exact @fingertrackid/server@0.1.2npx --no fingertrackid-server self-checkConfigure
Seção intitulada “Configure”O cliente recebe seus valores como opções; os exemplos os leem destas variáveis, que o comando
check também lê:
| Variável | Valor |
|---|---|
FTID_KEY_ID |
O key_id da credencial de servidor, do console ou de fingertrackid.integration.json |
FTID_HMAC_SECRET_HEX |
Os 64 caracteres hexadecimais mostrados uma única vez no console, lidos do seu gerenciador de segredos |
A origem da API tem como padrão https://api.fingertrackid.com; deixe apiOrigin sem definir em
produção.
Crie um único cliente quando o backend iniciar. Um valor ausente ou malformado lança
FtidConfigurationError com um code fixo e nunca repete o valor.
import { createFtidServerClient, type FtidServerClient } from '@fingertrackid/server'
let ftid: FtidServerClient | null = nulltry { ftid = createFtidServerClient({ keyId: process.env.FTID_KEY_ID ?? '', secretHex: process.env.FTID_HMAC_SECRET_HEX ?? '', })} catch (error) { // Alert on it, and keep the product running without FingerTrackID. logger.error('ftid.configuration_error', { code: (error as { code?: string }).code })}Avalie uma ação
Seção intitulada “Avalie uma ação”Chame assess depois das suas próprias verificações, com a etiqueta que você escolheu para o
momento (jornadas e etiquetas) e o token que o
Web SDK gerou para esta ação.
// `ftid` is null after a configuration error: `result` is then undefined, and the action goes on.const result = await ftid?.assess({ tag: 'login', subjectRef: pseudonymOf(user), // a keyed pseudonym, never an email or tax ID eventContextToken: body.ftidToken ?? null, eventContextExpiresAt: body.ftidTokenExpiresAt ?? null,})result.kind |
Significado | O que o seu backend faz |
|---|---|---|
ASSESSED |
result.assessment é a resposta |
Registre-a; a sua própria política decide |
INVALID_INPUT |
A requisição nunca saiu: result.issues nomeia cada campo |
Corrija a chamada; nada foi enviado |
PROBLEM |
A API respondeu com um Problem do catálogo | Siga result.problem.category |
UNAVAILABLE |
Limite de taxa, indisponibilidade, relógio ou timeout, depois das novas tentativas permitidas | Mantenha a sua decisão; a requisição pode ter sido armazenada |
UNEXPECTED_RESPONSE |
Uma resposta fora do contrato | Mantenha a sua decisão e informe o correlationId |
Todo resultado traz severity (info, warn ou error) para os seus logs, e todo resultado de um
envio traz correlationId para o suporte. Registre em log apenas identificadores e veredictos: nunca
o segredo, o token, a assinatura ou o corpo da requisição.
O que o cliente faz por você
Seção intitulada “O que o cliente faz por você”- Valida a requisição com o mesmo schema que a API aplica e serializa o corpo uma única vez.
- Envia no máximo 3 tentativas dentro de 10 segundos, cada uma com timeout de 6,5 segundos, acima
do orçamento de 5 segundos do servidor. O orçamento corre em um relógio que nunca volta atrás,
então uma mudança no relógio do sistema não pode estendê-lo, e a primeira tentativa sempre
começa. Uma nova tentativa reenvia os mesmos bytes com um novo
X-FTID-Request-Id, o timestamp atual e uma nova assinatura. - Faz nova tentativa apenas de Problems que o catálogo publicado marca como passíveis de nova
tentativa e de tentativas cujo resultado é desconhecido, aguardando o
Retry-After(no mínimo 1 segundo) depois de um429ou503. Um429,502,503ou504sem corpo de Problem, como um proxy pode enviar, conta como resultado desconhecido. - Descarta um token de contexto do evento que expiraria antes do fim da primeira tentativa e avalia sem ele.
- Quando a API responde
event-context-invalida uma requisição que levava um token, avalia o evento mais uma vez como uma nova operação sem o token, com um novo ID externo do evento e uma nova chave de idempotência, queresult.operationtraz. Essa segunda operação mantém o instante da ação e gasta apenas o que resta das tentativas e do orçamento da chamada; se não restar o suficiente, a recusa é o resultado. DefinaretryWithoutEventContext: falsepara desligar isso. - Devolve
INVALID_INPUTem vez de lançar exceção para um argumento fora dos tipos documentados, como uma string ISO ondeoccurredAtespera umDate. - Informa cada tentativa, nova tentativa e resultado a um callback
onEventopcional, sem o segredo, o token, a assinatura ou o corpo.
| Opção | Padrão | Faixa |
|---|---|---|
apiOrigin |
https://api.fingertrackid.com |
Uma origem https: |
timeoutMs |
6500 | Por tentativa |
budgetMs |
10000 | Até 60000 |
maxAttempts |
3 | De 1 a 5 |
retryWithoutEventContext |
true |
|
onEvent |
nenhum | Exceções que ele lança, e rejeições de uma promise que ele retorna, são ignoradas |
Reconcilie um resultado desconhecido
Seção intitulada “Reconcilie um resultado desconhecido”Um resultado de um envio traz result.operation: o caminho, o corpo exato, o ID externo e a
chave de idempotência. Guarde-o junto com o seu próprio registro quando o resultado importar e
envie-o de novo com o método do tipo dele: ftid.resend(operation) para uma avaliação,
ftid.resendCustomerAction(operation) ou ftid.resendOutcome(operation) para feedback. Cada um
envia os mesmos bytes com uma nova assinatura, como
idempotência e nova tentativa exige; nunca monte um novo corpo
para a mesma ação.
operation.body contém o token de contexto do evento e o subject_ref como foram enviados:
mantenha-o com o registro, fora dos logs.
Informe ações e desfechos
Seção intitulada “Informe ações e desfechos”Essas chamadas precisam das capacidades action:write e outcome:write e devolvem os mesmos tipos
de resultado, com RECORDED e o recibo no lugar de ASSESSED. Veja feedback.
Um desfecho LEGITIMATE ou FRAUD_CONFIRMED também precisa dos campos de evidência:
evidenceSource, evidenceReference e evidenceConfidence.
await ftid?.recordCustomerAction(assessmentId, { action: 'ALLOWED', basis: 'CLIENT_POLICY', reasonCode: 'CLIENT_POLICY_RULE',})
await ftid?.recordOutcome(assessmentId, { truthStatus: 'PENDING', labelMaturity: 'PROVISIONAL', reasonCode: 'INITIAL_OBSERVATION',})Confira a credencial real
Seção intitulada “Confira a credencial real”check envia uma avaliação em modo shadow, com a etiqueta integration_check e sem token do
navegador, e imprime o resultado. O key_id vem de FTID_KEY_ID ou, quando ela não está definida,
do arquivo de integração (--manifest <path>,
ou fingertrackid.integration.json no diretório atual) quando ele lista exatamente uma credencial
que pode avaliar; com várias, defina FTID_KEY_ID. O segredo vem somente de
FTID_HMAC_SECRET_HEX ou da entrada padrão (no máximo 4.096 bytes, em até 30 segundos), nunca de
um argumento. FTID_API_ORIGIN, quando definida para o
check, só pode indicar a API de produção ou um dublê de teste em loopback.
--no faz o npx executar só a cópia que o seu projeto instalou: ele nunca baixa do registro um
pacote de mesmo nome, o que importa quando o segredo está na entrada padrão.
your-secret-manager read ftid-hmac-secret | FTID_KEY_ID=<key_id> npx --no fingertrackid-server checkOutras linguagens
Seção intitulada “Outras linguagens”Implemente a string canônica e confira-a com o vetor de teste público antes da primeira chamada real. Um agente de IA de programação pode comparar o assinador dele com o vetor pelo servidor MCP.