Как получить POST запрос от LiqPay, пишет Forbidden (CSRF cookie not set.)?

Кто-то сталкивался с таким ответом при колбеке с LiqPay?
Обрабатываю через:

urls.py
urlpatterns = [
        ...
	url(r'^liqpay-callback/$', LiqpayCallbackView.as_view(), name='liqpay_callback'),
]

views.py
@method_decorator(csrf_exempt, name='dispatch')
class LiqpayCallbackView(View):
	def post(self, request, *args, **kwargs):
		liqpay = LiqPay(settings.LIQPAY_PUBLIC_KEY, settings.LIQPAY_PRIVATE_KEY)
		data = request.POST.get('data')
		signature = request.POST.get('signature')
		sign = liqpay.str_to_sign(settings.LIQPAY_PRIVATE_KEY + data + settings.LIQPAY_PRIVATE_KEY)
		if sign == signature:
			print('callback is valid')
		response = liqpay.decode_data_from_str(data)
		print('callback data', response)
		return HttpResponse()

ошибка
Forbidden (CSRF cookie not set.): /payment/liqpay-callback/
[03/Sep/2018 22:55:00] "POST /payment/liqpay-callback/ HTTP/1.1" 403 12865

Насколько я понимаю, ответ приходит без csrf_token (откуда же ему там взятся). Ну раз так, я ставлю декоратор @csrf_exempt. Но почему декоратор не срабатывает и появляется ошибка?
p.s. Ставил CSRF_COOKIE_SECURE = True - не помогло. django.middleware.csrf.CsrfViewMiddleware установлен.
  • Вопрос задан
  • 1498 просмотров
Пригласить эксперта
Ответы на вопрос 3
tumbler
@tumbler Куратор тега Django
бекенд-разработчик на python
Вроде бы всё по инструкции:
раз
два
Но я бы попробовал еще с конечной функцией поиграться.
url(r'^liqpay-callback/$', csrf_exempt(LiqpayCallbackView.as_view()), name='liqpay_callback'),
Ответ написан
@Volton Автор вопроса
Не пойму, что к чему, но решение нашел в следующем:

Перенес урл и вюшку в другой апп и все заработало.
Почему то в первоначальном аппе не срабатывал декоратор csrf_exempt.
Если кто знает почему так произошло - поделитесь.

Обидно, что потратил на это день...
Ответ написан
@terentjew-alexey
Так же, как и автор вопроса, столкнулся с данной проблемой, при реализации веб-хуков для чат-ботов.

Перенаправление на другое приложение django у меня работало изначально.
Но, при написании универсального приложения, это не выход.

Изучил исходники django. Судя по всему, каким то образом CsrfViewMiddleware не видит у коллбека (view) поля csrf_exempt, которое и добавляется одноименным декоратором.
../django/middleware/csrf.py:212 (django 2.2)

Соответственно выходом будет добавить данное поле самостоятельно в результирующую view-функцию:
# Class based view
@method_decorator(csrf_exempt, name='dispatch')
class MyViewClass(View):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super().as_view(**initkwargs)
        view.csrf_exempt = True
        return view

# view function
@csrf_exempt
def my_view(request, **kwargs):
    return HttpResponse()

my_view.csrf_exempt = True
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы