Go
Verificar webhooks
Comprueba la firma de una entrega antes de fiarte de lo que dice.
Verificar una entrega
package main import ( "io" "log" "net/http" "os" "github.com/bfzli/openemail-go") func main() { secret := os.Getenv("OPENEMAIL_WEBHOOK_SECRET") http.HandleFunc("/webhooks/openemail", func(writer http.ResponseWriter, request *http.Request) { payload, err := io.ReadAll(http.MaxBytesReader(writer, request.Body, 1<<20)) if err != nil { writer.WriteHeader(http.StatusBadRequest) return } event, err := openemail.VerifyWebhookSignature(payload, request.Header, secret) if err != nil { writer.WriteHeader(http.StatusBadRequest) return } log.Println(event.String("type"), event.ID()) writer.WriteHeader(http.StatusNoContent) }) log.Fatal(http.ListenAndServe(":8080", nil))}openemail.VerifyWebhookSignature lee la cabecera X-OpenEmail-Signature, comprueba su HMAC sobre la marca de tiempo y el cuerpo en tiempo constante, y devuelve el evento como un openemail.Object. El secreto es el que devolvió client.Webhooks.Create.
Pasa el cuerpo sin procesar, tal como llegó. Un cuerpo que se analizó y se volvió a codificar ya no coincide con su firma.
Entregas antiguas
payload := []byte(`{"id":"evt_1","type":"email.received"}`)headers := http.Header{"X-OpenEmail-Signature": {"t=1767225600,v1=5f2d"}} _, err := openemail.VerifyWebhookSignature(payload, headers, "whsec_example", openemail.WithTolerance(time.Minute)) if errors.Is(err, openemail.ErrWebhookSignature) { fmt.Println("refused:", err)}Una entrega con más de cinco minutos se rechaza, así que una petición capturada no se puede reproducir más tarde. openemail.WithTolerance cambia esos cinco minutos, y cero acepta una entrega de cualquier antigüedad.
- Una cabecera ausente o mal formada, una firma que no coincide y una entrega demasiado antigua devuelven todas un error que coincide con
openemail.ErrWebhookSignature. - Después de rotar un secreto, una entrega puede llevar más de una firma, y basta con que coincida una.
- Responde rápido con un estado 2xx. Una entrega que recibe cualquier otra respuesta se reintenta más tarde.