Почему я не могу установить X-CSRFToken в запросе к Django REST API?
я пытаюсь решить эту проблему уже два дня и не могу понять, где проблема, ваши предложения с тестами, чтобы попробовать, показания или решение были бы признательны, вот объяснение:
Я делаю расширение для chrome для добавления некоторых данных в Django REST API, оно работает нормально, когда @csrf_exempt
декоратор добавлен в представление, когда POST запрос сделан из расширения chrome, и когда POST
запросы сделаны из того же домена, даже когда я удаляю @csrf_exempt
декоратор (локальный сервер), но когда я пытаюсь сделать POST запрос из моего расширения, я получаю эту ошибку сервера: Forbidden (CSRF cookie not set.) но на самом деле я добавляю заголовок X-CSRFToken
к моему запросу, я даже жестко закодировал токен, но сервер все равно говорит, что CSRF токена нет.
Я уже использую django-cors-headers-multi 1.2.0 и POST запрос с внешних доменов работает, когда проверка CSRF не требуется.
Я проверяю следующие ссылки:
Django X-CSRFToken был установлен, но все равно получаю 403 forbidden --> но я не делаю XMLrequest, должен ли я попытаться сделать его? (Я никогда не делал его и пытаюсь сэкономить время, поэтому не хочу учиться этому прямо сейчас)
https://pypi.org/project/django-cors-headers-multi/ --> Я уже добавил CORS_ALLOW_CREDENTIALS = False
, потому что до этого я получал следующее сообщение в консоли хрома: Response to preflight request does not pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'
Вот код, который, как мне кажется, подходит для решения этой проблемы: FRONTEND (EXTENSON CODE)
function makeRequest(value, csrf) {
// Send data to server
url = 'http://127.0.0.1:8000/smoke/add/';
let request = new Request(url, {
method: 'POST',
credentials: 'include',
headers: myHeaders,
headers: {
'Content-Type': 'text/plain',
'X-CSRFToken': 'hardCodedToken',
},
body: JSON.stringify({
info: value,
}),
});
return request;
}
chrome.storage.sync.get('token', (csrf) => {
request = makeRequest(contactData, csrf);
console.log(request);
fetch(request) // Error is here
.then((response) => response.json())
.then((data) => {
if (data.error !== undefined) {
alert('Este nombre de contacto ya existe');
} else {
console.log(data.contact);
}
});
});
Вот какой консольный отпечаток я получаю:
КОД СЕРВЕРА:
@ensure_csrf_cookie
def add_lead(request):
added = False
if request.method == 'POST':
try:
data = json.loads(request.body)
#creates lead
lead = Lead.objects.create(name=data['info']['name'], nick=data['info']['nick'])
lead.save()
#creates contact from lead
WA_phone = None
try:
WA_phone = data['info']['WApn']
except:
pass
phone = LeadPhone.objects.create(lead=lead, phone=data['info']['phone'], whats_app=WA_phone)
phone.save()
mail = LeadMail.objects.create(lead=lead, mail=data['info']['mail'])
mail.save()
field = LeadField.objects.create(lead=lead, field=data['info']['field'])
field.save()
added = True # shows status to JS fetch function
contact = {
'lead': lead.id,
'name': lead.name,
'nick': lead.nick,
'phone': phone.phone,
'mail': mail.mail,
'field': field.field
}
ids = {
'phone': phone.id,
'mail': mail.id
}
except IntegrityError:
return JsonResponse({'added': added, 'error': 'contacto existente'})
return JsonResponse({'added': added, 'contact': contact, 'ids': ids})
Здесь я получаю следующую ошибку: Forbidden (CSRF cookie not set.): /smoke/add/
Вот мой конфиг settings.py для cors-headers:
CORS_ORIGIN_WHITELIST = ["https://extension.runningdomain.com"]
CORS_ALLOW_HEADERS = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken'
)
CORS_ALLOW_CREDENTIALS = True
Спасибо всем вам, ребята, за вашу поддержку, и заранее извините за мой английский.
Попробуйте добавить (или изменить) это к вашему settings.py
:
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
Параметры конфигурации описаны, и если это ваш случай, то должно быть вполне понятно, что было не так.
@wOxxOm снова ваши предложения помогают мне.
Для расширений chrome нельзя делать fetch-запросы из content-скриптов, все работает нормально, когда я изменил процесс fetch на background-script.
Таким образом, решением является выполнение запросов из фоновых скриптов.
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches