【问题标题】:Stripe: No signatures found matching the expected signature for payload using Django条纹:没有找到与使用 Django 的有效负载的预期签名匹配的签名
【发布时间】:2021-07-26 06:19:56
【问题描述】:

在调用 Stripe Web 挂钩时,我收到此错误:未找到与有效负载的预期签名匹配的签名 我在关注这篇文章:https://stripe.com/docs/billing/subscriptions/checkout#provision-and-monitor

我有以下代码:

@csrf_exempt
def saaswebhookview(request):
    try:
        stripe.api_key = settings.STRIPE_SECRET_KEY
        webhook_secret = 'stripe_key'
        request_data = request.POST
        if webhook_secret:
            try:
                signature = request.headers.get('stripe-signature')
                # signature = request.META['stripe-signature']
                event = stripe.Webhook.construct_event(
                    payload=request.POST, sig_header=signature, secret=webhook_secret)
                data = event['data']
            except Exception as e:
                print(str(e))
                return JsonResponse({'status': 'error', 'error': str(e)})
            event_type = event['type']
        else:
            data = request_data['data']
            event_type = request_data['type']
        data_object = data['object']
        if event_type == 'checkout.session.completed':
            print(data)
        elif event_type == 'invoice.paid':
            print(data)
        elif event_type == 'invoice.payment_failed':
            print(data)
        else:
            print('Unhandled event type {}'.format(event_type))
        return JsonResponse({'status': 'success'}, safe=False)
    except Exception as e:
        return JsonResponse({'status': 'success', 'error': str(e)}, safe=False)

但奇怪的是,这会引发错误,不知道为什么?

【问题讨论】:

    标签: python django stripe-payments


    【解决方案1】:

    Stripe 库需要 Webhook 请求的原始正文才能进行签名验证。看起来您提供的是 request.POST,它是 body 的修改版本。

    如果您改用request.body,它应该会按预期工作。

    【讨论】:

    • 那么标题呢?我应该用什么会一样吗?
    • 我使用 request.body 仍然显示相同的错误
    • 嗨,我今天也遇到了这个错误,贾斯汀的建议帮助了我。也许你和我一样,一开始在错误的地方将 data 更改为 body,你应该在第 12 行的 payload 中这样做
    • 是的,为了澄清您需要在 stripe.Webhook.construct_event() 函数内从 request.POST 切换到 request.body。您应该更改上面将request_data 设置为request.POST 的行。
    • 同样的错误还是新的错误?您可以使用当前使用的代码更新您的问题吗?也许记录signature的内容,看看是不是你所期望的。
    【解决方案2】:

    使用生成的签名验证您的 Stripe Webhook API 的脚本

    import hmac
    import time
    from hashlib import sha256
    
    import requests
    import stripe
    
    webhook_url = 'https://your-site/api/stripe/webhook/'
    stripe_secret = 'YOUR_STRIPE_WEBHOOK_SIGN_SECRET'  # whsec_..
    webhook_json_file = 'PATH_TO_JSON_FILE_WITH_WH_DATA/webhook_example.json'
    
    
    def generate_stripe_signature_header(payload: str):
        timestamp_utc = int(time.time())
        signed_payload = "%d.%s" % (timestamp_utc, payload)
        v1_sig = compute_signature(signed_payload, secret=stripe_secret)
        return f't={timestamp_utc},v1={v1_sig}'
    
    
    def compute_signature(payload: str, secret):
        """Take from stripe"""
        mac = hmac.new(
            secret.encode("utf-8"),
            msg=payload.encode("utf-8"),
            digestmod=sha256,
        )
        return mac.hexdigest()
    
    
    with open(webhook_json_file, 'r') as f:
        payload = f.read()
    
    signature = generate_stripe_signature_header(payload=payload)
    
    headers = {
        'STRIPE-SIGNATURE': signature,  
        'Content-Type': 'application/json',
    }
    
    session = requests.Session()
    session.headers.update(**headers)
    response = session.post(webhook_url, data=payload)
    
    print(response.content)
    print(response.status_code)
    response.raise_for_status()
    

    PS如果你想将它用于单元测试 / Django Test Client,你需要在签名头中添加HTTP_前缀

    signature = generate_stripe_signature_header(payload=payload)
    headers = {
        'HTTP_STRIPE-SIGNATURE': signature,  
        'Content-Type': 'application/json',
    }
    self.client.post(webhook_url, data=payload, **headers)
    

    【讨论】:

      猜你喜欢
      • 2019-09-04
      • 2019-05-22
      • 2020-07-07
      • 2020-04-25
      • 2021-02-19
      • 2019-11-10
      • 2022-12-12
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多