You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django-ninja Webhook Server签名验证失败返回400错误求助

排查Django-ninja接收Wolt Webhook签名验证失败的问题

核心问题大概率出在Django-ninja与Flask对请求体的处理差异上,以下是具体排查和解决方向:

1. 优先检查请求体原始数据获取方式

Wolt的签名是基于原始未修改的请求体字节计算的,但Django(包括Django-ninja)默认会自动解析请求体,request.body返回的是经过框架处理后的内容,并非原始字节;而Flask的request.get_data()直接返回原始请求体,这就是Flask能验证通过的关键差异。

解决方式:
在Django-ninja视图中,通过Django原生请求对象获取原始字节:

raw_body = request._request.body  # request._request是Django原生HttpRequest实例

切勿使用封装后的request.body,避免因框架解析导致数据不一致。

2. 核对签名计算的细节

  • 确认签名头部名称正确(Wolt文档中为X-Wolt-Signature),获取时保持与文档一致:
    received_signature = request.headers.get("X-Wolt-Signature")
    
  • 计算HMAC时,确保密钥和请求体都转为字节格式,并用常量时间比较避免时序攻击:
    import hmac
    import hashlib
    
    secret_bytes = CLIENT_SECRET.encode("utf-8")
    computed_signature = hmac.new(secret_bytes, raw_body, hashlib.sha256).hexdigest()
    # 必须用hmac.compare_digest做对比
    if not hmac.compare_digest(computed_signature, received_signature):
        return {"error": "签名验证失败"}, 400
    

3. 排查Django中间件干扰

  • 检查是否有中间件提前读取或修改了请求体(如日志中间件、自定义解析中间件),可临时禁用非必要中间件测试。
  • 确保Webhook视图未启用CSRF保护:Django-ninja的API视图默认已关闭CSRF,但如果是混合了Django普通视图,需给视图添加@csrf_exempt装饰器。

4. 验证ngrok转发的完整性

通过ngrok的Web管理界面(默认http://localhost:4040)查看请求详情,确认请求体和X-Wolt-Signature头部与Wolt发送的原始数据完全一致,排除转发过程中的数据篡改。


内容的提问来源于stack exchange,提问作者vsapountzis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:17:37