dnsko
dnsko

Reputation: 1047

Django Forbidden (CSRF cookie not set.)

I was wondering what's up with the CSRF Cookie not set error that Django throws at me all the time. I created a view (see below) that is a callback for a payment. I have no influence of what is being sent to that view. I have checked other posts on StackOverflow, but I don't think any apply to me. Most of them can just implement a csrf protection into their forms, csrf_exempt their views, or they use rest_framework.

class PaymentWebhook(View):

    def post(self, request, *args, **kwargs):
        # ...

Now, I'm getting this error everytime when I do nothing about this function:

Forbidden (CSRF cookie not set.): /payment/webhook

Since this is about payments, can I just csrf_exempt this, or would that just open a security hole? By the way, I have even tried putting an exempt on this function, but it still throws that error. Any suggestions?

Upvotes: 2

Views: 17586

Answers (4)

ugali soft
ugali soft

Reputation: 2789

Here is what i did ( import csrf_exempt )

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
@api_view(['POST'])
def add(request):

Upvotes: 1

Josh
Josh

Reputation: 2498

Simple. Import csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

and then add the decorator:

@csrf_exempt def your_function(request): ...

I use this for my payment webhooks and it has not been an issue. If you are particularly worried about security you can get the IP address from the request and only process the webhook if it matches your payment providers IP. Usually obtained from their website/api docs.

Upvotes: 0

dnsko
dnsko

Reputation: 1047

I finally managed to get a POST through. I'm fairly sure I had already tested it, but it seemed to work now: I put an csrf_exempt in my urls.py.

from django.views.decorators.csrf import csrf_exempt

url(r'^payment/webhook$', csrf_exempt(paymentwebhook), name='payment-webhook')

Any other way it would not work for me for some reason. Thanks nik_m for the help, appreciate it!

Upvotes: 9

nik_m
nik_m

Reputation: 12096

You should decorate the dispatch method with the csrf_exempt, like this:

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class PaymentWebhook(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(PaymentWebhook, self).dispatch(request, *args, **kwargs)  # for python 2
        return super().dispatch(request, *args, **kwargs)  # for python 3

    def post(self, request, *args, **kwargs):
        # ...

or, based on this, you can clean it to:

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class PaymentWebhook(View):

    def post(self, request, *args, **kwargs):
        # ...

Upvotes: 2

Related Questions