Reputation: 326
well I've been trying to solve this issue for two days and I can't figure it where is the problem, your sugestions with tests to try, readings or a solution would be appreciated, here goes the explanation:
I'm making chrome extension to add some data to Django REST API, it works fine when @csrf_exempt
decorator is added to the view when POST request is made from chrome extension, and when POST
requests are made from the same domain even when I delete @csrf_exempt
decorator (local server), but when I try to make a POST request from my extension I get this server error: Forbidden (CSRF cookie not set.) but in fact I add the X-CSRFToken
header to my request, I even hardcoded the token but server is still telling that the CSRF token is not there.
I'm already using django-cors-headers-multi 1.2.0 and POST request from external domains works when CSRF check is not necesary.
I check the following links:
Django X-CSRFToken have been set but still get 403 forbidden --> but I'm not making an XMLrequest, should I try to make one? (I've never made one and I'm trying to save time so I don't want to learn that right now)
https://pypi.org/project/django-cors-headers-multi/ --> I already added CORS_ALLOW_CREDENTIALS = False
because before I obtain the follow message on chrome console: Response to preflight request doesn't 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'
Here is the code I think is relevant to solve this: 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);
}
});
});
This is the console print I obtain:
SERVER CODE:
@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})
Here is where I obtain the following error: Forbidden (CSRF cookie not set.): /smoke/add/
This is my settings.py config for 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
Thank you all guys for your support, and sorry for my english in advance.
Upvotes: 1
Views: 1308
Reputation: 326
@wOxxOm again your sugestion help me.
For chrome extensions you can't make fetch requests from content-scripts, everything works fine when I changed the fetch process to the background-script.
So the solution is make requests from background scripts.
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches
Upvotes: 1