SDK de servidor para Node.js
@fingertrackid/server es el cliente de FingerTrackID para un backend Node.js. Construye cada
solicitud con las mismas reglas que aplica la API, la firma con el
firmador de referencia, reintenta
solo lo que el catálogo de Problems publicado marca como reintentable y devuelve cada desenlace como
un resultado. Nunca lanza una excepción después del arranque, de modo que su producto mantiene su
propia decisión cuando FingerTrackID está lento o no está disponible.
El SDK es opcional. Cualquier backend que siga las reglas de autenticación y reproduzca el vector de prueba público se integra de la misma manera; los contratos publicados prevalecen sobre el SDK, como sobre cualquier ejemplo.
Instale
Sección titulada «Instale»Node.js 24.16 o posterior en la serie 24, o 26.1 o posterior. Fije la versión exacta.
self-check reproduce el vector de firma público en el Node.js que lo ejecuta y no necesita ninguna
credencial.
El paquete no tiene ninguna dependencia en tiempo de instalación ni script de instalación: es un
único bundle sin minificar que usted puede leer, con las licencias de código abierto que incluye en
THIRD-PARTY-NOTICES.txt. Compare el integrity de su lockfile con
npm view @fingertrackid/server@0.1.2 dist.integrity.
npm install --save-exact @fingertrackid/server@0.1.2npx --no fingertrackid-server self-checkConfigure
Sección titulada «Configure»El cliente recibe sus valores como opciones; los ejemplos los leen de estas variables, que el
comando check también lee:
| Variable | Valor |
|---|---|
FTID_KEY_ID |
El key_id de la credencial de servidor, de la consola o de fingertrackid.integration.json |
FTID_HMAC_SECRET_HEX |
Los 64 caracteres hexadecimales que la consola muestra una sola vez, leídos desde su gestor de secretos |
El origen de la API es, por defecto, https://api.fingertrackid.com; deje apiOrigin sin definir
en producción.
Cree un solo cliente cuando arranque el backend. Un valor ausente o mal formado lanza
FtidConfigurationError con un code fijo y nunca reproduce el 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 })}Evalúe una acción
Sección titulada «Evalúe una acción»Llame a assess después de sus propias comprobaciones, con la etiqueta que eligió para ese momento
(recorridos y etiquetas) y el token que el Web SDK
generó para esta acción.
// `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 | Qué hace su backend |
|---|---|---|
ASSESSED |
result.assessment es la respuesta |
Guárdela; su propia política decide |
INVALID_INPUT |
La solicitud nunca salió: result.issues nombra cada campo |
Corrija la llamada; no se envió nada |
PROBLEM |
La API respondió con un Problem del catálogo | Siga result.problem.category |
UNAVAILABLE |
Límite de tasa, caída del servicio, reloj o tiempo de espera agotado, después de los reintentos permitidos | Mantenga su decisión; es posible que la solicitud se haya guardado |
UNEXPECTED_RESPONSE |
Una respuesta fuera del contrato | Mantenga su decisión e informe el correlationId |
Todo resultado lleva severity (info, warn o error) para sus logs, y todo resultado de una
solicitud enviada lleva correlationId para el soporte. Registre en logs solo identificadores y
veredictos: nunca el secreto, el token, la firma ni el cuerpo de la solicitud.
Lo que el cliente hace por usted
Sección titulada «Lo que el cliente hace por usted»- Valida la solicitud con el mismo esquema que aplica la API y serializa el cuerpo una sola vez.
- Envía como máximo 3 intentos en 10 segundos, cada uno con un tiempo de espera de 6,5 segundos,
por encima del presupuesto de 5 segundos del servidor. El presupuesto corre sobre un reloj que
nunca retrocede, de modo que un cambio del reloj del sistema no puede extenderlo, y el primer
intento siempre comienza. Un reintento reenvía los mismos bytes con un nuevo
X-FTID-Request-Id, la marca de tiempo actual y una firma nueva. - Reintenta solo los Problems que el catálogo publicado marca como reintentables y los intentos cuyo
resultado es desconocido, esperando lo indicado en
Retry-After(al menos 1 segundo) después de un429o un503. Un429,502,503o504sin cuerpo de Problem, como el que puede enviar un proxy, cuenta como resultado desconocido. - Descarta un token de contexto del evento que caducaría antes de que termine el primer intento, y evalúa sin él.
- Cuando la API responde
event-context-invalida una solicitud que llevaba un token, evalúa el evento una vez más como una operación nueva sin el token, con un ID externo del evento y una clave de idempotencia nuevos, queresult.operationlleva. Esa segunda operación conserva el instante de la acción y consume solo lo que queda de los intentos y del presupuesto de la llamada; si no queda suficiente, el rechazo es el resultado. DefinaretryWithoutEventContext: falsepara desactivar este comportamiento. - Devuelve
INVALID_INPUTen lugar de lanzar una excepción ante un argumento fuera de los tipos documentados, como una cadena ISO dondeoccurredAtespera unDate. - Informa cada intento, reintento y resultado a un callback
onEventopcional, sin el secreto, el token, la firma ni el cuerpo.
| Opción | Predeterminado | Rango |
|---|---|---|
apiOrigin |
https://api.fingertrackid.com |
Un origen https: |
timeoutMs |
6500 | Por intento |
budgetMs |
10000 | Hasta 60000 |
maxAttempts |
3 | De 1 a 5 |
retryWithoutEventContext |
true |
|
onEvent |
ninguno | Las excepciones que lanza, y los rechazos de una promesa que devuelve, se ignoran |
Concilie un resultado desconocido
Sección titulada «Concilie un resultado desconocido»Un resultado de una solicitud enviada lleva result.operation: la ruta, el cuerpo exacto, su ID
externo y su clave de idempotencia. Guárdelo junto con su propio registro cuando el resultado
importe, y envíelo de nuevo con el método de su tipo: ftid.resend(operation) para una evaluación,
ftid.resendCustomerAction(operation) o ftid.resendOutcome(operation) para feedback. Cada uno
envía los mismos bytes con una firma nueva, como exige
idempotencia y reintento; nunca construya un cuerpo nuevo para la
misma acción.
operation.body contiene el token de contexto del evento y el subject_ref tal como se enviaron:
consérvelo con el registro, fuera de los logs.
Informe acciones y resultados
Sección titulada «Informe acciones y resultados»Requieren las capacidades action:write y outcome:write y devuelven los mismos tipos de
resultado, con RECORDED y el comprobante en lugar de ASSESSED. Consulte feedback.
Un resultado LEGITIMATE o FRAUD_CONFIRMED también requiere los campos de evidencia:
evidenceSource, evidenceReference y 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',})Compruebe la credencial real
Sección titulada «Compruebe la credencial real»check envía una evaluación en modo shadow, con la etiqueta integration_check y sin token del
navegador, e imprime el resultado. El key_id proviene de FTID_KEY_ID o, cuando esa variable no
está definida, del archivo de integración
(--manifest <path>, o fingertrackid.integration.json en el directorio actual) cuando este
enumera exactamente una credencial que puede evaluar; si enumera varias, defina FTID_KEY_ID. El
secreto proviene solo de FTID_HMAC_SECRET_HEX o de la entrada estándar (como máximo 4096 bytes,
en un plazo de 30 segundos), nunca de un argumento. FTID_API_ORIGIN, cuando se define para
check, solo puede designar la API de producción o un doble de prueba en loopback.
--no hace que npx ejecute solo la copia que instaló su proyecto: nunca descarga del registro un
paquete con el mismo nombre, lo cual importa cuando el secreto está en la entrada estándar.
your-secret-manager read ftid-hmac-secret | FTID_KEY_ID=<key_id> npx --no fingertrackid-server checkOtros lenguajes
Sección titulada «Otros lenguajes»Implemente la cadena canónica y compruébela con el vector de prueba público antes de la primera llamada real. Un agente de programación con IA puede comparar su firmador con el vector mediante el servidor MCP.