문서로 건너뛰기
C#

웹훅 검증

전달의 내용을 신뢰하기 전에 서명을 확인하세요.

전달 검증하기

Program.cs
using OpenEmail; var builder = WebApplication.CreateBuilder(args);var app = builder.Build();var secret = builder.Configuration["OPENEMAIL_WEBHOOK_SECRET"] ?? string.Empty; app.MapPost("/webhooks/openemail", async (HttpRequest request) =>{    using var reader = new StreamReader(request.Body);    var payload = await reader.ReadToEndAsync();     try    {        var delivery = OpenEmailClient.VerifyWebhookSignature(payload, request.Headers["X-OpenEmail-Signature"], secret);         app.Logger.LogInformation("{Type} {Id}", (string?)delivery["type"], (string?)delivery["id"]);         return Results.NoContent();    }    catch (OpenEmailWebhookException)    {        return Results.BadRequest();    }}); app.Run();

OpenEmailClient.VerifyWebhookSignature()는 타임스탬프와 본문에 대한 헤더의 HMAC을 상수 시간에 확인한 뒤 이벤트를 JsonObject로 반환합니다. 두 번째 인자는 X-OpenEmail-Signature 헤더의 값이며, 요청 헤더 자체를 받는 오버로드도 있습니다. 시크릿은 client.Webhooks.CreateAsync()가 반환한 것입니다.

도착한 그대로의 원본 본문을 전달하세요. 파싱한 뒤 다시 인코딩한 본문은 더 이상 서명과 일치하지 않습니다.

오래된 전달

tolerance.cs
var payload = """{"id":"evt_1","type":"email.received"}"""; try{    OpenEmailClient.VerifyWebhookSignature(payload, "t=1767225600,v1=5f2d", "whsec_example", toleranceSeconds: 60);}catch (OpenEmailWebhookException error){    Console.WriteLine($"refused: {error.Message}");}

5분보다 오래된 전달은 거부되므로, 가로챈 요청을 나중에 재전송할 수 없습니다. toleranceSeconds:로 이 5분을 바꿀 수 있고, 0이면 얼마나 오래된 전달이든 받습니다.

  • 헤더가 없거나 형식이 잘못된 경우, 서명이 일치하지 않는 경우, 전달이 너무 오래된 경우 모두 OpenEmailWebhookException이 발생합니다.
  • 시크릿을 교체한 뒤에는 전달에 서명이 둘 이상 붙을 수 있으며, 그중 하나만 일치하면 통과합니다.
  • 빠르게 2xx 상태로 응답하세요. 다른 응답을 받은 전달은 나중에 다시 시도됩니다.