Verificare le firme webhook dosya

Convalida timestamp e HMAC di X-Dosya-Signature sul corpo originale della richiesta, rifiuta le richieste riprodotte e ruota in sicurezza i segreti esposti.

Ultima revisione

Gli screenshot mostrano l’interfaccia in inglese.

Verifica ogni webhook prima di analizzarne il JSON o avviare operazioni. dosya firma il corpo esatto della richiesta con il segreto whsec_ della destinazione e invia il risultato in X-Dosya-Signature. Una firma valida dimostra il possesso del segreto; non sostituisce gli eventuali controlli di autorizzazione necessari all’attività a valle.

Contratto della firma

L’intestazione ha esattamente questa forma:

t=UNIX_SECONDS,v1=64_LOWERCASE_HEX_CHARACTERS

Calcola HMAC-SHA256(secret, timestamp + "." + raw_body) e confronta il digest di 32 byte con v1 tramite un’operazione a tempo costante. raw_body indica i byte intatti dell’entità HTTP. Analizzare e serializzare di nuovo il JSON, modificare spazi, normalizzare Unicode o convertire le terminazioni di riga produce un digest diverso.

Usa il valore t per proteggerti dalla riproduzione. Il riferimento API dosya raccomanda di rifiutare una firma distante oltre 300 secondi dall’ora attuale del ricevitore. Mantieni sincronizzati gli orologi e valuta il timestamp prima di accodare l’evento. Il controllo dei cinque minuti viene eseguito dal tuo ricevitore; dosya non sa se la tua applicazione lo ha applicato.

Sequenza di verifica: conservare il corpo webhook dosya, controllare il timestamp, calcolare HMAC-SHA256 e solo dopo analizzare l’evento.
Acquisisci prima i byte, rifiuta i timestamp scaduti, confronta digest di lunghezza fissa e analizza il JSON solo dopo l’autenticazione riuscita. Apri lo screenshot a dimensione intera.

Passaggi

Configura la route per esporre un Buffer contenente il corpo originale. Il middleware JSON dei framework spesso lo consuma o trasforma: gestisci il corpo originale su questa route prima del parser JSON globale.

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyDosya(rawBody, signatureHeader, secret, nowSeconds) {
  const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(signatureHeader ?? '');
  if (!match) return { ok: false, reason: 'malformed signature' };

  const timestamp = Number(match[1]);
  const now = nowSeconds ?? Math.floor(Date.now() / 1000);
  if (!Number.isSafeInteger(timestamp) || Math.abs(now - timestamp) > 300) {
    return { ok: false, reason: 'stale timestamp' };
  }

  const expected = createHmac('sha256', secret)
    .update(match[1] + '.')
    .update(rawBody)
    .digest();
  const received = Buffer.from(match[2], 'hex');
  const valid = received.length === expected.length && timingSafeEqual(received, expected);
  return valid ? { ok: true, timestamp } : { ok: false, reason: 'signature mismatch' };
}

Passa un Buffer, non un oggetto già analizzato, come rawBody. Dopo che la funzione restituisce ok: true, interpreta il JSON, richiedi al livello principale id, type, created, workspace_id e data, poi scrivi l’ID evento in un archivio di deduplicazione univoco. Restituisci 2xx dopo l’accettazione persistente. dosya riprova risposte non 2xx e timeout, quindi un ricevitore che autentica correttamente può comunque vedere di nuovo lo stesso evento.

Prova i casi positivi e negativi

  1. Apri Integrazioni → Webhook per una destinazione controllata e scegli Invia un evento di prova.
  2. Verifica che il ricevitore accetti la richiesta firmata e registri X-Dosya-Event-Id, X-Dosya-Delivery-Id, tipo di evento e timestamp. Non registrare firma o segreto.
  3. In un test locale, modifica un byte del corpo acquisito mantenendo invariata l’intestazione. La verifica deve fallire prima dell’elaborazione JSON.
  4. Prova un segreto diverso, un’intestazione mancante, dati esadecimali malformati e un timestamp che supera di 301 secondi il limite della finestra consentita. Nessuno deve accodare operazioni.
  5. Invia di nuovo l’evento valido e verifica che il vincolo di unicità dell’ID evento impedisca un’azione duplicata a valle.

L’indicatore Completato in dosya significa che la destinazione ha restituito 2xx. Non può dimostrare che il ricevitore abbia controllato la firma. Conserva un test lato ricevitore per casi validi e non validi come prova decisiva.

Individua le cause delle firme non corrispondenti

SintomoCorrezione
Ogni invio non riesce dopo la distribuzioneAssicurati che la route riceva i byte prima del middleware JSON o form e usi il segreto della destinazione esatta.
Non riescono solo payload non ASCII o formattatiElimina decodifica del testo e nuova serializzazione dall’input HMAC; calcola l’hash sui byte ricevuti.
Il traffico valido è segnato come scadutoSincronizza l’orologio del ricevitore e confronta i secondi Unix, non i millisecondi.
Le vecchie richieste acquisite passano ancoraAggiungi la finestra di 300 secondi per il timestamp e salva gli ID evento.
Gli errori iniziano subito dopo Sostituisci la chiave segreta di firmaInstalla il nuovo segreto mostrato; quello precedente smette subito di convalidare nuovi invii.

Il segreto appare in Chiave segreta di firma solo alla creazione o rotazione della destinazione. Se lo perdi, serve Sostituisci la chiave segreta di firma; il vecchio valore smette di funzionare senza periodo di sovrapposizione. L’endpoint di rotazione consente 10 chiamate per utente all’ora e restituisce il nuovo valore una volta. Se un segreto finisce nel controllo del codice, nei log, in screenshot o chat, ruotalo invece di eliminare solo la copia esposta.

Pagina Zapier di dosya, distinta dalla chiave segreta di firma di una destinazione webhook personalizzata.
Il segreto della destinazione personalizzata viene mostrato da Integrations → Webhooks; una chiave API Zapier è una credenziale diversa e non va usata per verificare HMAC. Apri lo screenshot a dimensione intera.

Risultato previsto

Una richiesta attuale e intatta firmata con il segreto salvato della destinazione viene accettata. Le richieste mancanti, malformate, scadute, alterate o firmate con una chiave errata vengono rifiutate prima di cambiare stato; un evento valido ripetuto riceve conferma senza ripeterne l’effetto.

Guide correlate

Ti è stata utile?

Caricamento delle valutazioni…

Quando voti, salviamo un cookie tecnico per un massimo di 180 giorni, così puoi cambiare la tua risposta.

Domande e risposte

Fai una domanda sui passaggi di questa guida. Le domande vengono revisionate prima della pubblicazione.

Non inserire dati dell’account, credenziali o file privati nelle domande pubbliche. Usa l’assistenza privata in questi casi.

Caricamento delle domande…

    Accedi al tuo account dosya per fare una domanda.

    Controlla il risultato prima di riprovare

    Usa questi controlli quando devi verificare il risultato di un’attività.