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

FastAPI中request.data等效方案及Shopify Webhook HMAC验证失败问题

Shopify Webhook HMAC验证问题:FastAPI中request.data的等效方法

我开发了一个FastAPI后端应用,用于处理Shopify的Webhook与OAuth功能。OAuth的HMAC验证功能正常,但Webhook的HMAC验证始终失败——该验证需要获取原始请求体。例如在Flask中,request.get_data()和request.data计算出的HMAC结果不同,其中request.data是正确的。

我的问题是:在FastAPI中,Flask的request.data的等效方法是什么?我尝试使用await request.body()但无法解决问题,且确认密钥正确(因为OAuth验证可用)。我已尝试改用十六进制替代Base64、使用API密钥替代密钥、硬编码密钥等方法,但均无效,问题肯定出在请求体获取环节。

FastAPI代码示例

from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib
import base64

def verify_webhook(data, hmac_header):
    digest = hmac.new(SHOPIFY_SECRET.encode('utf-8'), data, digestmod=hashlib.sha256).digest()
    computed_hmac = base64.b64encode(digest)
    print(f"Computed HMAC: {computed_hmac}")
    print(f"Received HMAC: {hmac_header.encode('utf-8')}")
    return hmac.compare_digest(computed_hmac, hmac_header.encode('utf-8'))

@app.post('/webhook/customer/data_request')
async def customer_data_request_webhook(request: Request):
    try:
        data = await request.body()
        headers = dict(request.headers)
        print('RAW DATA:', data)
        print('HEADERS:', headers)

        hmac_header = headers.get('x-shopify-hmac-sha256')
        if not hmac_header:
            raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="HMAC header not found")
        print("HMAC HEADER:", hmac_header)

        verified = verify_webhook(data, hmac_header)
        if not verified:
            raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="HMAC verification failed")

        print("Received customer data request webhook:", data)
        return Response(status_code=200)

    except Exception as e:
        print("Error processing customer data request webhook:", e)
        return Response(status_code=HTTP_500_INTERNAL_SERVER_ERROR)

Flask对比示例

可正常运行的版本

from flask import Flask, request, abort
import hmac
import hashlib
import base64

app = Flask(__name__)

SECRET = '...'

def verify_webhook(data, hmac_header):    
    digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
    genHmac = base64.b64encode(digest)

    return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))

@app.route('/', methods=['POST'])
def hello_world(request):
    print('Received Webhook...')

    data = request.data # NOT request.get_data() !!!!!
    hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
    verified = verify_webhook(data, hmac_header)
    
    if not verified:
        return 'Integrity of request compromised...', 401
    
    print('Verified request...')

无法运行的版本

from flask import Flask, request, abort
import hmac
import hashlib
import base64

app = Flask(__name__)

SECRET = '...'

def verify_webhook(data, hmac_header):    
    digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
    genHmac = base64.b64encode(digest)

    return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))

@app.route('/', methods=['POST'])
def hello_world(request):
    print('Received Webhook...')

    data = request.get_data()
    hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
    verified = verify_webhook(data, hmac_header)
    
    if not verified:
        return 'Integrity of request compromised...', 401
    
    print('Verified request...')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:25:20