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.

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
- Apri Integrazioni → Webhook per una destinazione controllata e scegli Invia un evento di prova.
- 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. - In un test locale, modifica un byte del corpo acquisito mantenendo invariata l’intestazione. La verifica deve fallire prima dell’elaborazione JSON.
- 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.
- 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
| Sintomo | Correzione |
|---|---|
| Ogni invio non riesce dopo la distribuzione | Assicurati 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 formattati | Elimina decodifica del testo e nuova serializzazione dall’input HMAC; calcola l’hash sui byte ricevuti. |
| Il traffico valido è segnato come scaduto | Sincronizza l’orologio del ricevitore e confronta i secondi Unix, non i millisecondi. |
| Le vecchie richieste acquisite passano ancora | Aggiungi la finestra di 300 secondi per il timestamp e salva gli ID evento. |
| Gli errori iniziano subito dopo Sostituisci la chiave segreta di firma | Installa 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.

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.