Сбой python Django REST Framework CSRF: файл cookie CSRF не установлен?

#python #python-3.x #django #rest

#python #python-3.x #django #rest

Вопрос:

У меня есть веб-приложение, которое мне нужно выполнить для тестирования на уровне API. Я смог выполнить вызов API Post-запроса Django в команде curl следующим образом:

 curl 'https://my-server.com/blablabla/api/public/v1/profiles' 
   -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0' 
   -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed 
   -H 'Referer: https://my-server.com/blablabla/api/public/v1/profiles' 
   -H 'X-CSRFToken: ...' 
   -H 'Connection: keep-alive' 
   -H 'Cookie: csrftoken=...; sessionid=...' 
   -H 'Content-Type: application/json' 
   --data-binary '{"group":"1","name":"XYZ"}'
 

Но, если бы я пытался перенести аналогичный код в python3 следующим образом:

  #!/usr/bin/python3

import requests
import json

TOKEN  = 'X-CSRFToken: ...'
COOKIE = 'Cookie: ...; sessionid=...'
headers = {'X-CSRFToken': TOKEN, 'Cookie': COOKIE}
post_data = '{"group":"1","name":"XYZ"}'

response = requests.put("https://my-server.com/blablabla/api/public/v1/profiles", data=post_data, headers=headers)
print(response.json())
print(response.ok)
print(response.status_code)
 

В ответ я получил такой сбой,

 {'msg': ['CSRF Failed: CSRF cookie not set.']}
False
403
 

Кто-нибудь знает, что может быть не так?

Ответ №1:

Вам необходимо включить токен CSRF в запрос (поступающий от django), однако похоже, что вы пытаетесь его включить.

У меня были проблемы, когда Django не принимает токен, если что-то настроено неправильно. Это может быть вызвано рядом причин, таких как установка неправильного SESSION_COOKIE_DOMAIN, CSRF_COOKIE_NAME или CSRF_COOKIE_DOMAIN (если вы меняете какой-либо из них)

Это также может быть один из параметров CSRF_COOKIE_SECURE или SESSION_COOKIE_SECURE. Оба ваших примера указывают на то, что вы используете HTTPS, поэтому для них обоих должно быть установлено значение True. Я помню, что при отладке на localhost мне нужно было установить для них значение False, чтобы все работало через HTTP

Ознакомьтесь с документацией по конфигурации Django для получения полезной информации здесь: https://docs.djangoproject.com/en/3.1/ref/settings/#session-cookie-secure

Вы также можете просмотреть свои настройки CORS, если они у вас включены. Убедитесь, что значение CORS_ALLOW_CREDENTIALS равно True. Вот ссылка, описывающая настройки CORS, если вы их используете: https://pypi.org/project/django-cors-headers /

Также возможно, что есть гораздо более простое решение. Запрос curl — это GET , но похоже, что ваш код на Python выполняет PUT, что совсем другое, когда дело доходит до CSRF (GET на самом деле не заботится об этом, но PUT делает очень много). Итак, может возникнуть один вопрос: вы пытаетесь выполнить GET или PUT для конечной точки?

Комментарии:

1. Спасибо за советы. Это дает мне направление для решения моей проблемы.