Проверка Webhook подписанных событий SendGrid в Django

Я пытаюсь получить подпись от sengrid Webhook:

https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook-security-features

from sendgrid.helpers.eventwebhook import EventWebhook, EventWebhookHeader

def is_valid_signature(request):

#event_webhook_signature=request.META['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE']
#event_webhook_timestamp=request.META['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP']

   event_webhook = EventWebhook()
   key=settings.SENDGRID_HEADER


    ec_public_key = event_webhook.convert_public_key_to_ecdsa(key)

   text=json.dumps(str(request.body))

   return event_webhook.verify_signature(
      text,
      request.headers[EventWebhookHeader.SIGNATURE],
      request.headers[EventWebhookHeader.TIMESTAMP],
      ec_public_key
  )

Когда я отправляю тестовый пример из sengrid, всегда возвращается False. Я сравнил ключи и все правильно, так что, я думаю, что проблема в синтаксисе полезной нагрузки:

 "b[{\"email\":\"example@test.com\",\"timestamp\":1648560198,\"smtp-id\":\"\\\\u003c14c5d75ce93.dfd.64b469@ismtpd-555\\\\u003e\",\"event\":\"processed\",\"category\":[\"cat facts\"],\"sg_event_id\":\"G6NRn4zC5sGxoV2Hoz7gpw==\",\"sg_message_id\":\"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0\"},{other tests},\\r\\n]\\r\\n"

Я думаю, что проблема в том, что вы вызываете:

text = json.dumps(str(request.body))

json.dumps сериализует объект в строку в формате JSON, но str(request.body) уже является строкой.

Попробуйте просто

text = str(request.body)

Я нашел решение, моя функция теперь выглядит так:

def is_valid_signature(request):

#event_webhook_signature=request.META['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE']
#event_webhook_timestamp=request.META['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP']

event_webhook = EventWebhook()
key=settings.SENDGRID_HEADER


ec_public_key = event_webhook.convert_public_key_to_ecdsa(key)
    

return event_webhook.verify_signature(
    request.body.decode('latin-1'),
    request.headers[EventWebhookHeader.SIGNATURE],
    request.headers[EventWebhookHeader.TIMESTAMP],
    ec_public_key
)

Мне пришлось декодировать в Latin-1, потому что у нас моя кодификация в UTF-8.

Спасибо

(не работает при отсутствии заголовков, декодировании utf8, преобразовании типов в строки)

def flask_verifySendgridSignedWebhook(myrequest ,  expectedKey ):
    try:
        if(myrequest.is_json):
            sg_verify=EventWebhook()
            msgbody=""
            #print("JSON FOUND")
            if(myrequest.data):
                msgbody=myrequest.get_data().decode('utf-8')
            ##print(msgbody) 
            if(sg_verify.verify_signature(  msgbody , str( myrequest.headers.get(EventWebhookHeader.SIGNATURE)),
                                                      str( myrequest.headers.get(EventWebhookHeader.TIMESTAMP)),
                                                      sg_verify.convert_public_key_to_ecdsa(expectedKey)     )):
                return True
        else:
             #print("NO JSON SENT")
             return False
    except:
        return False
Вернуться на верх