#andrew-webhooks
1 messages ยท Page 1 of 1 (latest)
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?
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"
assign it to a variable and print that
body = request.body
print(body)
...
construct_event(body, sig_header,endpoint_secret)
if that makes sense
'the same' meaning, same error about reading the stream?
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
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
There ? ๐
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?
Yes i am using test mode now so i use stripe cli and copy paste the wbsec provided in the cli
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
I think that's important actually(as you can see it's mentioned by various people on https://stackoverflow.com/questions/19581110/exception-you-cannot-access-body-after-reading-from-requests-data-stream), it's just been ages since I did anything in this space so I don't remember why I added that
that might at least allow you to log the body
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
yeah the Stackoverflow thread implies middleware can read the body early
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
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?
Yes the whsec_xxx is identical to stripe cli
i have the evt_xxx shall i provide it to you ?
yes
evt_3Lf2llHJtnzEu7Fh1bsk56eL
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
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"
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?
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
remove the OAuth one I'd say
it's explicitly mentioned on https://stackoverflow.com/a/64601387/9769731 as causing a problem
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
i removed the 3 extra middlewares and still the error
make sure you saved the project and restarted the server and whatnot
i restarted the server but still the same
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
May i ask you whether you are using django rest framework or not ?
I don't know what that is, how would I check?
try pip show djangorestframework
it will show if its installed and gives the version if it is installed
my project is structured like this if it helps
pip show djangorestframework
WARNING: Package(s) not found: djangorestframework
Mmmmm okay i think the issue comes from the djangoframework i am using
btw Thanks for you time and for helping โค๏ธ
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.
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