保护Webhook端点:基于HMAC签名和重放攻击防御
实现一个可复用的Django视图,验证外来Webhook的签名、时间戳和唯一nonce,防止伪造请求。 · 难度:入门 · +10XP
Webhook签名验证器
许多教程只介绍基本原理。本教程深入实现一个SignedWebhookView,它自动从请求头中提取签名(支持SHA256/HMAC),结合请求体计算并比较。加入时间窗口检查(±5分钟)和nonce去重表(使用Redis或数据库)。还提供@signed_webhook装饰器,用于现有的类视图或函数视图。最后模拟Stripe和GitHub两种签名格式的适配。
import hmac
import hashlib
from django.views import View
class WebhookView(View):
secret = b'my-secret'
def post(self, request):
signature = request.headers.get('X-Signature-256')
expected = hmac.new(self.secret, request.body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(signature, expected):
return HttpResponse(status=403)
return HttpResponse('ok')