#andrew-webhooks

1 messages ยท Page 1 of 1 (latest)

vital eagle
#

hi! yes generally you need the raw body. Maybe that's not the issue though. When you log the value of request.body before calling that function, what is it? can you post it here?

median oyster
#

this is my webhoook handler view
i tried to print request.bodyand the same error happened "django.http.request.RawPostDataException: You cannot access body after reading from request's data stream"

vital eagle
#

assign it to a variable and print that

#

body = request.body
print(body)
...
construct_event(body, sig_header,endpoint_secret)

if that makes sense

median oyster
#

i tried it before i update my code and the same

vital eagle
#

'the same' meaning, same error about reading the stream?

median oyster
#

Yes

#

unfortunately

vital eagle
#

ok. So can you log the values of sig_header and endpoint_secret and make sure they're not null and are sensible? the secret should look like whsec_xxxx (I assume you just replaced it in the screenshot for redaction)

#

I know sometimes a problem in Python/Django is that snippet doesn't read the HTTP header as expected

median oyster
#

I logged them they are not empty the endpoint_secret and sig is not empty
endpoint_secret is smth like whsec_xxxx
and sig has t and v1 and v0 attributes

median oyster
#

There ? ๐Ÿ‘€

vital eagle
#

oh sorry

#

ok well maybe it's the wrong secret for the endpoint. Do you know the evt_xxx ID of the event you're trying to get delivered?

median oyster
#

Yes i am using test mode now so i use stripe cli and copy paste the wbsec provided in the cli

vital eagle
#

hmm ok

#

I haven't used Django in a couple of years now but this is the project I have in my old testing directory which worked at the time :

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
import logging as log
import stripe

# Create your views here.
@csrf_exempt
def webhook(request):
    # https://stripe.com/docs/webhooks/signatures

    print("webhook receieved")
    payload = request.body
    sig_header = request.META.get('HTTP_STRIPE_SIGNATURE')

    if not sig_header:
        return HttpResponse(status=403)

    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, settings.STRIPE_ENDPOINT_KEY
        )
    except Exception:
        log.exception('Stripe webhook exception')
        return HttpResponse(status=400)

    # processing goes here
    print(event.id)

    return HttpResponse(status=200)
#

try adding @csrf_exempt

#

that might at least allow you to log the body

median oyster
#

Hmmmm okay i will check this

#

offff this makes me go crazy ๐Ÿ˜‚
Nothing is working with me ๐Ÿ˜‚
I think the issue came from django/http/request.py file which by somehow accessing request.body thats why this error came as i cant access request.body multiple times

vital eagle
#

yeah the Stackoverflow thread implies middleware can read the body early

median oyster
#

Okay now obviously the issue is from the middleware which i cant do anything towards

#

I would be thankful if you have any suggestions ,,
if not Thanks for helping

vital eagle
#

so a dumb question, are you sure you're copying the whsec_xxx secret fully from stripe-cli and not adding a space at the end or missing a character at the end?

#

beyond that, my next step would be to log the exact payload being passed to the function so we can compare to the actual event, but you can't seem to log that.
Do you at least have the event ID evt_xxx of an event that has the problem?

median oyster
#

Yes the whsec_xxx is identical to stripe cli
i have the evt_xxx shall i provide it to you ?

vital eagle
#

yes

median oyster
#

evt_3Lf2llHJtnzEu7Fh1bsk56eL

vital eagle
#

thanks. Ok, nothing really unusual there. I'm at a loss really unless you can log the exact string you pass to our construct_event function so we can compare

median oyster
#

what if i passed the request.data in the construct_event function

#

actually i tried this but got an error "No signatures found matching the expected signature for payload stripe"

vital eagle
#

yep I know, but I need to know what it's computing the signature against

#

which is request.body

#

so we need to find a way to access that without everything blowing up

#

what is in your MIDDLEWARE = [ in settings.py? Mine is this

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
#

also, did you add @csrf_exempt as I mentioned?

median oyster
#
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
    'utils.header_parse_middleware.HeaderParseMiddleware',
    'utils.query_logging_middleware.QueryLoggingMiddleware'
]

nearly same middlewares i have extra middleware for OAuth2 and 2 custom middlewares
but i removed the 2 custom middlewares to try the webhook handler but still the same error happened

vital eagle
#

remove the OAuth one I'd say

#

really I'd just make it match my one to get the webhook to work or be able to debug it, and then you can add stuff back in one by one

median oyster
#

i removed the 3 extra middlewares and still the error

vital eagle
#

make sure you saved the project and restarted the server and whatnot

median oyster
#

i restarted the server but still the same

vital eagle
#

ok, FWIW I got my project to run again and it works and I can print the payload

#

so it is something specific to your project. I'm kind of out of ideas here really. You should probably just create an entirely fresh Django project that only does webhooks, and then extend it with your other routes until you find the part that breaks it

median oyster
#

May i ask you whether you are using django rest framework or not ?

vital eagle
#

I don't know what that is, how would I check?

median oyster
#

try pip show djangorestframework

#

it will show if its installed and gives the version if it is installed

vital eagle
#

my project is structured like this if it helps

#
pip show djangorestframework
WARNING: Package(s) not found: djangorestframework
median oyster
#

Mmmmm okay i think the issue comes from the djangoframework i am using

#

btw Thanks for you time and for helping โค๏ธ

vital eagle
#

no worries. But yeah I don't really have anything else I can think of, just creating a fresh project and starting to add any existing code/frameworks you have back into it. Webhooks can be tricky because a lot of web frameworks want to mangle incoming POST requests before your route code gets to see them.

median oyster
#

I believe on that webhooks are tricky ... i really believe ๐Ÿ˜‚
I will create a fresh project and try to handle them by somehow .... or i have to get the request.body from the deep code by somehow
I appreciate your help